<commit_before>/*
 * Copyright 2001-2004 The Apache Software Foundation.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 * 
 */

package org.apache.jmeter.reporters;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.io.RandomAccessFile;
import java.io.Serializable;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;

import org.apache.avalon.framework.configuration.Configuration;
import org.apache.avalon.framework.configuration.ConfigurationException;
import org.apache.avalon.framework.configuration.DefaultConfigurationBuilder;
//import org.apache.avalon.framework.configuration.DefaultConfigurationSerializer;
import org.apache.jmeter.engine.event.LoopIterationEvent;
import org.apache.jmeter.engine.util.NoThreadClone;
import org.apache.jmeter.samplers.Clearable;
import org.apache.jmeter.samplers.Remoteable;
import org.apache.jmeter.samplers.SampleEvent;
import org.apache.jmeter.samplers.SampleListener;
import org.apache.jmeter.samplers.SampleResult;
import org.apache.jmeter.samplers.SampleSaveConfiguration;
import org.apache.jmeter.save.OldSaveService;
import org.apache.jmeter.save.SaveService;
import org.apache.jmeter.save.TestResultWrapper;
import org.apache.jmeter.testelement.TestElement;
import org.apache.jmeter.testelement.TestListener;
import org.apache.jmeter.testelement.property.BooleanProperty;
import org.apache.jmeter.testelement.property.ObjectProperty;
import org.apache.jorphan.logging.LoggingManager;
import org.apache.log.Logger;
import org.xml.sax.SAXException;

/**
 */
public class ResultCollector extends AbstractListenerElement implements
      SampleListener, Clearable, Serializable, TestListener, Remoteable,
      NoThreadClone
{
   static final long serialVersionUID = 1;
   private static final String TESTRESULTS_START = "<testResults>";
   private static final String TESTRESULTS_END = "</testResults>";
   private static final String XML_HEADER = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>";
   private static final int MIN_XML_FILE_LEN = XML_HEADER.length()
         + TESTRESULTS_START.length() + TESTRESULTS_END.length();
   transient private static Logger log = LoggingManager.getLoggerForClass();
   public final static String FILENAME = "filename";
   public final static String SAVE_CONFIG = "saveConfig";
   private static boolean functionalMode = false;
   public static final String ERROR_LOGGING = "ResultCollector.error_logging";
   // protected List results = Collections.synchronizedList(new ArrayList());
   //private int current;
   //transient private DefaultConfigurationSerializer serializer;
   //private boolean inLoading = false;
   transient private volatile PrintWriter out;
   private boolean inTest = false;
   private static Map files = new HashMap();
   private Set hosts = new HashSet();
   protected boolean isStats = false;

   /**
    * No-arg constructor.
    */
   public ResultCollector()
   {
      //current = -1;
      //serializer = new DefaultConfigurationSerializer();
      setErrorLogging(false);
      setProperty(new ObjectProperty(SAVE_CONFIG,new SampleSaveConfiguration()));
   }

   private void setFilenameProperty(String f)
   {
      setProperty(FILENAME, f);
   }

   public String getFilename()
   {
      return getPropertyAsString(FILENAME);
   }

   public boolean isErrorLogging()
   {
      return getPropertyAsBoolean(ERROR_LOGGING);
   }

   public void setErrorLogging(boolean errorLogging)
   {
      setProperty(new BooleanProperty(ERROR_LOGGING, errorLogging));
   }

   /**
    * Sets the filename attribute of the ResultCollector object.
    * 
    * @param f
    *           the new filename value
    */
   public void setFilename(String f)
   {
      if (inTest) { return; }
      setFilenameProperty(f);
   }

   public void testEnded(String host)
   {
      hosts.remove(host);
      if (hosts.size() == 0)
      {
         finalizeFileOutput();
         inTest = false;
      }
   }

   public void testStarted(String host)
   {
      hosts.add(host);
      try
      {
         initializeFileOutput();
         if (getVisualizer() != null){
         	this.isStats = getVisualizer().isStats();
         }
      }
      catch (Exception e)
      {
         log.error("", e);
      }
      inTest = true;
   }

   public void testEnded()
   {
      testEnded("local");
   }

   public void testStarted()
   {
      testStarted("local");
   }

   public void loadExistingFile() throws IOException
   {
      //inLoading = true;
      boolean parsedOK = false;
      if (new File(getFilename()).exists())
      {
         clearVisualizer();
         BufferedReader dataReader = null;
         try
         {
            readSamples(SaveService.loadTestResults(new BufferedInputStream(
                  new FileInputStream(getFilename()))));
            parsedOK = true;
         }
         catch (Exception e)
         {
            log.warn("File load failure, trying old data format.");
            try
            {
               Configuration savedSamples = getConfiguration(getFilename());
               Configuration[] samples = savedSamples.getChildren();
               for (int i = 0; i < samples.length; i++)
               {
                   SampleResult result = OldSaveService.getSampleResult(samples[i]);
                   sendToVisualizer(result);
               }
            }
            catch (Exception e1)
            {
               log.warn("Error parsing XML results " + e);
               log.info("Assuming CSV format instead");
               dataReader = new BufferedReader(new FileReader(getFilename()));
               String line;
               while ((line = dataReader.readLine()) != null)
               {
                  sendToVisualizer(OldSaveService
                        .makeResultFromDelimitedString(line));
               }
               parsedOK = true;
            }
         }
         finally
         {
            if (dataReader != null) dataReader.close();
            if (!parsedOK)
            {
               SampleResult sr = new SampleResult();
               sr.setSampleLabel("Error loading results file - see log file");
               sendToVisualizer(sr);
            }
         }
      }
      //inLoading = false;
   }

   private static void writeFileStart(PrintWriter writer,SampleSaveConfiguration saveConfig)
   {
      if (saveConfig.saveAsXml())
      {
         writer.println(XML_HEADER);
         writer.println(TESTRESULTS_START);
      }
      else if (saveConfig.saveFieldNames())
         {
            writer.println(OldSaveService.printableFieldNamesToString());
         }
   }

   private static void writeFileEnd(PrintWriter pw,SampleSaveConfiguration saveConfig)
   {
      if (saveConfig.saveAsXml())
      {
         pw.print("\n");
         pw.print(TESTRESULTS_END);
      }
   }

   private static synchronized PrintWriter getFileWriter(String filename,SampleSaveConfiguration saveConfig)
         throws IOException
   {
      if (filename == null || filename.length() == 0) { return null; }
      PrintWriter writer = (PrintWriter) files.get(filename);
      boolean trimmed = true;

      if (writer == null)
      {
         if (saveConfig.saveAsXml())
         {
            trimmed = trimLastLine(filename);
         }
         // Find the name of the directory containing the file
         // and create it - if there is one
         File pdir = new File(filename).getParentFile();
         if (pdir != null) pdir.mkdirs();
         writer = new PrintWriter(
               new OutputStreamWriter(new BufferedOutputStream(
                     new FileOutputStream(filename, trimmed)), "UTF-8"), true);
         files.put(filename, writer);
      }
      if (!trimmed)
      {
         writeFileStart(writer,saveConfig);
      }
      return writer;
   }

   // returns false if the file did not contain the terminator
   private static boolean trimLastLine(String filename)
   {
      RandomAccessFile raf = null;
      try
      {
         raf = new RandomAccessFile(filename, "rw");
         long len = raf.length();
         if (len < MIN_XML_FILE_LEN) { return false; }
         raf.seek(len - TESTRESULTS_END.length() - 10);//TODO: may not work on
                                                       // all OSes?
         String line;
         long pos = raf.getFilePointer();
         int end = 0;
         while ((line = raf.readLine()) != null)// reads to end of line OR file
         {
            end = line.indexOf(TESTRESULTS_END);
            if (end >= 0) // found the string
            {
               break;
            }
            pos = raf.getFilePointer();
         }
         if (line == null)
         {
            log.warn("Unexpected EOF trying to find XML end marker in "
                  + filename);
            raf.close();
            return false;
         }
         raf.setLength(pos + end);// Truncate the file
         raf.close();
      }
      catch (FileNotFoundException e)
      {
         return false;
      }
      catch (IOException e)
      {
         log.warn("Error trying to find XML terminator " + e.toString());
         try
         {
            if (raf != null) raf.close();
         }
         catch (IOException e1)
         {
         }
         return false;
      }
      return true;
   }

   public static void enableFunctionalMode(boolean mode)
   {
      functionalMode = mode;
   }

   public boolean getFunctionalMode()
   {
      return functionalMode || isErrorLogging();
   }

   /**
    * Gets the serializedSampleResult attribute of the ResultCollector object.
    * 
    * @param result
    *           description of the Parameter
    * @return the serializedSampleResult value
    */
   //NOTUSED
//   private String getSerializedSampleResult(SampleResult result)
//         throws SAXException, IOException, ConfigurationException
//   {
//      ByteArrayOutputStream tempOut = new ByteArrayOutputStream();
//
//      serializer.serialize(tempOut, OldSaveService.getConfiguration(result,
//            getFunctionalMode()));
//      String serVer = tempOut.toString();
//
//      return serVer.substring(serVer.indexOf(System
//            .getProperty("line.separator")));
//   }

   private void readSamples(TestResultWrapper testResults) throws Exception
   {
      Collection samples = testResults.getSampleResults();
      Iterator iter = samples.iterator();
      while (iter.hasNext())
      {
         SampleResult result = (SampleResult) iter.next();
         sendToVisualizer(result);
      }
   }

   /**
    * Gets the configuration attribute of the ResultCollector object.
    * 
    * @return the configuration value
    */
   private Configuration getConfiguration(String filename) throws SAXException,
         IOException, ConfigurationException
   {
      DefaultConfigurationBuilder builder = new DefaultConfigurationBuilder();

      return builder.buildFromFile(filename);
   }

   public void clearVisualizer()
   {
      //current = -1;
      if (getVisualizer() != null && getVisualizer() instanceof Clearable)
      {
         ((Clearable) getVisualizer()).clear();
      }
      finalizeFileOutput();
   }

//   public void setListener(Object l)
//   {
//   }

   public void sampleStarted(SampleEvent e)
   {
   }

   public void sampleStopped(SampleEvent e)
   {
   }

   /**
    * When a test result is received, display it and save it.
    * 
    * @param e
    *           the sample event that was received
    */
   public void sampleOccurred(SampleEvent e)
   {
      SampleResult result = e.getResult();

      if (!isErrorLogging() || !result.isSuccessful())
      {
         sendToVisualizer(result);
		 
		 SampleSaveConfiguration config = getSaveConfig();
		 result.setSaveConfig(config);
		 
		 try
         {
            if (!config.saveAsXml())
            {
               if (out != null)
               {
                  String savee = OldSaveService.resultToDelimitedString(result);
                  out.println(savee);
               }
            }
            // Save results as XML
            else
            {
               recordResult(result);
            }
         }
         catch (Exception err)
         {
            log.error("", err); // should throw exception back to caller
         }
      }
   }

   protected void sendToVisualizer(SampleResult r)
   {
      if (getVisualizer() != null)
      {
         getVisualizer().add(r);
      }
   }

   private void recordResult(SampleResult result) throws Exception
   {
      if (out != null)
      {
         if (!isResultMarked(result) && !this.isStats)
         {
            SaveService.saveSampleResult(result, out);
         }
      }
   }

   /**
    * recordStats is used to save statistics generated by
    * visualizers
    * @param e
    * @throws Exception
    */
   public void recordStats(TestElement e) throws Exception
   {
   	  if (out == null){
   	  	 initializeFileOutput();
   	  }
   	  if (out != null){
   	  	 SaveService.saveTestElement(e,out);
   	  }
   }
   
   private synchronized boolean isResultMarked(SampleResult res)
   {
      String filename = getFilename();
      boolean marked = res.isMarked(filename);

      if (!marked)
      {
         res.setMarked(filename);
      }
      return marked;
   }

   private void initializeFileOutput() throws IOException
   {

      String filename = getFilename();
      if (out == null && filename != null)
      {
         if (out == null)
         {
            try
            {
               out = getFileWriter(filename,getSaveConfig());
            }
            catch (FileNotFoundException e)
            {
               out = null;
            }
         }
      }
   }

   private synchronized void finalizeFileOutput()
   {
      if (out != null)
      {
         writeFileEnd(out,getSaveConfig());
         out.close();
         files.remove(getFilename());
         out = null;
      }
   }

   /*
    * (non-Javadoc)
    * 
    * @see TestListener#testIterationStart(LoopIterationEvent)
    */
   public void testIterationStart(LoopIterationEvent event)
   {
   }
   /**
    * @return Returns the saveConfig.
    */
   public SampleSaveConfiguration getSaveConfig()
   {
      return (SampleSaveConfiguration)getProperty(SAVE_CONFIG).getObjectValue();
   }
   /**
    * @param saveConfig The saveConfig to set.
    */
   public void setSaveConfig(SampleSaveConfiguration saveConfig)
   {
      getProperty(SAVE_CONFIG).setObjectValue(saveConfig);
   }
}<commit_msg>Fixing issue when saving to old format and then trying to load back into 2.1<commit_after>/*
 * Copyright 2001-2004 The Apache Software Foundation.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 * 
 */

package org.apache.jmeter.reporters;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.io.RandomAccessFile;
import java.io.Serializable;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;

import org.apache.avalon.framework.configuration.Configuration;
import org.apache.avalon.framework.configuration.ConfigurationException;
import org.apache.avalon.framework.configuration.DefaultConfigurationBuilder;
//import org.apache.avalon.framework.configuration.DefaultConfigurationSerializer;
import org.apache.jmeter.engine.event.LoopIterationEvent;
import org.apache.jmeter.engine.util.NoThreadClone;
import org.apache.jmeter.samplers.Clearable;
import org.apache.jmeter.samplers.Remoteable;
import org.apache.jmeter.samplers.SampleEvent;
import org.apache.jmeter.samplers.SampleListener;
import org.apache.jmeter.samplers.SampleResult;
import org.apache.jmeter.samplers.SampleSaveConfiguration;
import org.apache.jmeter.save.OldSaveService;
import org.apache.jmeter.save.SaveService;
import org.apache.jmeter.save.TestResultWrapper;
import org.apache.jmeter.testelement.TestElement;
import org.apache.jmeter.testelement.TestListener;
import org.apache.jmeter.testelement.property.BooleanProperty;
import org.apache.jmeter.testelement.property.ObjectProperty;
import org.apache.jorphan.logging.LoggingManager;
import org.apache.log.Logger;
import org.xml.sax.SAXException;

/**
 */
public class ResultCollector extends AbstractListenerElement implements
      SampleListener, Clearable, Serializable, TestListener, Remoteable,
      NoThreadClone
{
   static final long serialVersionUID = 1;
   private static final String TESTRESULTS_START = "<testResults>";
   private static final String TESTRESULTS_END = "</testResults>";
   private static final String XML_HEADER = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>";
   private static final int MIN_XML_FILE_LEN = XML_HEADER.length()
         + TESTRESULTS_START.length() + TESTRESULTS_END.length();
   transient private static Logger log = LoggingManager.getLoggerForClass();
   public final static String FILENAME = "filename";
   public final static String SAVE_CONFIG = "saveConfig";
   private static boolean functionalMode = false;
   public static final String ERROR_LOGGING = "ResultCollector.error_logging";
   // protected List results = Collections.synchronizedList(new ArrayList());
   //private int current;
   //transient private DefaultConfigurationSerializer serializer;
   //private boolean inLoading = false;
   transient private volatile PrintWriter out;
   private boolean inTest = false;
   private static Map files = new HashMap();
   private Set hosts = new HashSet();
   protected boolean isStats = false;

   /**
    * No-arg constructor.
    */
   public ResultCollector()
   {
      //current = -1;
      //serializer = new DefaultConfigurationSerializer();
      setErrorLogging(false);
      setProperty(new ObjectProperty(SAVE_CONFIG,new SampleSaveConfiguration()));
   }

   private void setFilenameProperty(String f)
   {
      setProperty(FILENAME, f);
   }

   public String getFilename()
   {
      return getPropertyAsString(FILENAME);
   }

   public boolean isErrorLogging()
   {
      return getPropertyAsBoolean(ERROR_LOGGING);
   }

   public void setErrorLogging(boolean errorLogging)
   {
      setProperty(new BooleanProperty(ERROR_LOGGING, errorLogging));
   }

   /**
    * Sets the filename attribute of the ResultCollector object.
    * 
    * @param f
    *           the new filename value
    */
   public void setFilename(String f)
   {
      if (inTest) { return; }
      setFilenameProperty(f);
   }

   public void testEnded(String host)
   {
      hosts.remove(host);
      if (hosts.size() == 0)
      {
         finalizeFileOutput();
         inTest = false;
      }
   }

   public void testStarted(String host)
   {
      hosts.add(host);
      try
      {
         initializeFileOutput();
         if (getVisualizer() != null){
         	this.isStats = getVisualizer().isStats();
         }
      }
      catch (Exception e)
      {
         log.error("", e);
      }
      inTest = true;
   }

   public void testEnded()
   {
      testEnded("local");
   }

   public void testStarted()
   {
      testStarted("local");
   }

   public void loadExistingFile() throws IOException
   {
      //inLoading = true;
      boolean parsedOK = false;
      if (new File(getFilename()).exists())
      {
         clearVisualizer();
         BufferedReader dataReader = null;
         try
         {
            readSamples(SaveService.loadTestResults(new BufferedInputStream(
                  new FileInputStream(getFilename()))));
            parsedOK = true;
         }
         catch (Exception e)
         {
            log.warn("File load failure, trying old data format.");
            try
            {
               Configuration savedSamples = getConfiguration(getFilename());
               Configuration[] samples = savedSamples.getChildren();
               for (int i = 0; i < samples.length; i++)
               {
                   SampleResult result = OldSaveService.getSampleResult(samples[i]);
                   sendToVisualizer(result);
               }
            }
            catch (Exception e1)
            {
               log.warn("Error parsing XML results " + e);
               log.info("Assuming CSV format instead");
               dataReader = new BufferedReader(new FileReader(getFilename()));
               String line;
               while ((line = dataReader.readLine()) != null)
               {
                  sendToVisualizer(OldSaveService
                        .makeResultFromDelimitedString(line));
               }
               parsedOK = true;
            }
         }
         finally
         {
            if (dataReader != null) dataReader.close();
            if (!parsedOK)
            {
               SampleResult sr = new SampleResult();
               sr.setSampleLabel("Error loading results file - see log file");
               sendToVisualizer(sr);
            }
         }
      }
      //inLoading = false;
   }

   private static void writeFileStart(PrintWriter writer,SampleSaveConfiguration saveConfig)
   {
      if (saveConfig.saveAsXml())
      {
         writer.println(XML_HEADER);
         writer.println(TESTRESULTS_START);
      }
      else if (saveConfig.saveFieldNames())
         {
            writer.println(OldSaveService.printableFieldNamesToString());
         }
   }

   private static void writeFileEnd(PrintWriter pw,SampleSaveConfiguration saveConfig)
   {
      if (saveConfig.saveAsXml())
      {
         pw.print("\n");
         pw.print(TESTRESULTS_END);
      }
   }

   private static synchronized PrintWriter getFileWriter(String filename,SampleSaveConfiguration saveConfig)
         throws IOException
   {
      if (filename == null || filename.length() == 0) { return null; }
      PrintWriter writer = (PrintWriter) files.get(filename);
      boolean trimmed = true;

      if (writer == null)
      {
         if (saveConfig.saveAsXml())
         {
            trimmed = trimLastLine(filename);
         }
         // Find the name of the directory containing the file
         // and create it - if there is one
         File pdir = new File(filename).getParentFile();
         if (pdir != null) pdir.mkdirs();
         writer = new PrintWriter(
               new OutputStreamWriter(new BufferedOutputStream(
                     new FileOutputStream(filename, trimmed)), "UTF-8"), true);
         files.put(filename, writer);
      }
      if (!trimmed)
      {
         writeFileStart(writer,saveConfig);
      }
      return writer;
   }

   // returns false if the file did not contain the terminator
   private static boolean trimLastLine(String filename)
   {
      RandomAccessFile raf = null;
      try
      {
         raf = new RandomAccessFile(filename, "rw");
         long len = raf.length();
         if (len < MIN_XML_FILE_LEN) { return false; }
         raf.seek(len - TESTRESULTS_END.length() - 10);//TODO: may not work on
                                                       // all OSes?
         String line;
         long pos = raf.getFilePointer();
         int end = 0;
         while ((line = raf.readLine()) != null)// reads to end of line OR file
         {
            end = line.indexOf(TESTRESULTS_END);
            if (end >= 0) // found the string
            {
               break;
            }
            pos = raf.getFilePointer();
         }
         if (line == null)
         {
            log.warn("Unexpected EOF trying to find XML end marker in "
                  + filename);
            raf.close();
            return false;
         }
         raf.setLength(pos + end);// Truncate the file
         raf.close();
      }
      catch (FileNotFoundException e)
      {
         return false;
      }
      catch (IOException e)
      {
         log.warn("Error trying to find XML terminator " + e.toString());
         try
         {
            if (raf != null) raf.close();
         }
         catch (IOException e1)
         {
         }
         return false;
      }
      return true;
   }

   public static void enableFunctionalMode(boolean mode)
   {
      functionalMode = mode;
   }

   public boolean getFunctionalMode()
   {
      return functionalMode || isErrorLogging();
   }

   /**
    * Gets the serializedSampleResult attribute of the ResultCollector object.
    * 
    * @param result
    *           description of the Parameter
    * @return the serializedSampleResult value
    */
   //NOTUSED
//   private String getSerializedSampleResult(SampleResult result)
//         throws SAXException, IOException, ConfigurationException
//   {
//      ByteArrayOutputStream tempOut = new ByteArrayOutputStream();
//
//      serializer.serialize(tempOut, OldSaveService.getConfiguration(result,
//            getFunctionalMode()));
//      String serVer = tempOut.toString();
//
//      return serVer.substring(serVer.indexOf(System
//            .getProperty("line.separator")));
//   }

   private void readSamples(TestResultWrapper testResults) throws Exception
   {
      Collection samples = testResults.getSampleResults();
      Iterator iter = samples.iterator();
      while (iter.hasNext())
      {
         SampleResult result = (SampleResult) iter.next();
         sendToVisualizer(result);
      }
   }

   /**
    * Gets the configuration attribute of the ResultCollector object.
    * 
    * @return the configuration value
    */
   private Configuration getConfiguration(String filename) throws SAXException,
         IOException, ConfigurationException
   {
      DefaultConfigurationBuilder builder = new DefaultConfigurationBuilder();

      return builder.buildFromFile(filename);
   }

   public void clearVisualizer()
   {
      //current = -1;
      if (getVisualizer() != null && getVisualizer() instanceof Clearable)
      {
         ((Clearable) getVisualizer()).clear();
      }
      finalizeFileOutput();
   }

//   public void setListener(Object l)
//   {
//   }

   public void sampleStarted(SampleEvent e)
   {
   }

   public void sampleStopped(SampleEvent e)
   {
   }

   /**
    * When a test result is received, display it and save it.
    * 
    * @param e
    *           the sample event that was received
    */
   public void sampleOccurred(SampleEvent e)
   {
      SampleResult result = e.getResult();

      if (!isErrorLogging() || !result.isSuccessful())
      {
         sendToVisualizer(result);
		 
		 SampleSaveConfiguration config = getSaveConfig();
		 result.setSaveConfig(config);
		 
		 try
         {
            if (!config.saveAsXml())
            {
               if (out != null)
               {
                  String savee = OldSaveService.resultToDelimitedString(result);
                  out.println(savee);
               }
            }
            // Save results as XML
            else
            {
               recordResult(result);
            }
         }
         catch (Exception err)
         {
            log.error("", err); // should throw exception back to caller
         }
      }
   }

   protected void sendToVisualizer(SampleResult r)
   {
      if (getVisualizer() != null)
      {
         getVisualizer().add(r);
      }
   }

   private void recordResult(SampleResult result) throws Exception
   {
      if (out != null)
      {
         if (!isResultMarked(result) && !this.isStats)
         {
            SaveService.saveSampleResult(result, out);
         }
      }
   }

   /**
    * recordStats is used to save statistics generated by
    * visualizers
    * @param e
    * @throws Exception
    */
   public void recordStats(TestElement e) throws Exception
   {
   	  if (out == null){
   	  	 initializeFileOutput();
   	  }
   	  if (out != null){
   	  	 SaveService.saveTestElement(e,out);
   	  }
   }
   
   private synchronized boolean isResultMarked(SampleResult res)
   {
      String filename = getFilename();
      boolean marked = res.isMarked(filename);

      if (!marked)
      {
         res.setMarked(filename);
      }
      return marked;
   }

   private void initializeFileOutput() throws IOException
   {

      String filename = getFilename();
      if (out == null && filename != null)
      {
         if (out == null)
         {
            try
            {
               out = getFileWriter(filename,getSaveConfig());
            }
            catch (FileNotFoundException e)
            {
               out = null;
            }
         }
      }
   }

   private synchronized void finalizeFileOutput()
   {
      if (out != null)
      {
         writeFileEnd(out,getSaveConfig());
         out.close();
         files.remove(getFilename());
         out = null;
      }
   }

   /*
    * (non-Javadoc)
    * 
    * @see TestListener#testIterationStart(LoopIterationEvent)
    */
   public void testIterationStart(LoopIterationEvent event)
   {
   }
   /**
    * @return Returns the saveConfig.
    */
   public SampleSaveConfiguration getSaveConfig()
   {
      try 
      {
          return (SampleSaveConfiguration)getProperty(SAVE_CONFIG).getObjectValue();
      }
      catch(ClassCastException e)
      {
          setSaveConfig(new SampleSaveConfiguration());
          return getSaveConfig();
      }
   }
   /**
    * @param saveConfig The saveConfig to set.
    */
   public void setSaveConfig(SampleSaveConfiguration saveConfig)
   {
      getProperty(SAVE_CONFIG).setObjectValue(saveConfig);
   }
}
{'fraction_non_alphanumeric': 0.09675236806495263, 'fraction_numerical': 0.0018686771054836008, 'mean_word_length': 2.1802254098360656, 'pattern_counts': {'":': 0, '<': 13, '<?xml version=': 2, '>': 11, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 4}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 4, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5041657', 'n_tokens_mistral': 8416, 'n_tokens_neox': 8200, 'n_words': 2033}