org.testng.reporters.FileStringBuffer Maven / Gradle / Ivy
Show all versions of testng Show documentation
package org.testng.reporters;
import org.testng.log4testng.Logger;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.Reader;
import java.io.StringReader;
import java.io.Writer;
/**
* A string buffer that flushes its content to a temporary file whenever the internal string buffer
* becomes larger than MAX. If the buffer never reaches that size, no file is ever created and
* everything happens in memory, so the overhead compared to StringBuffer/StringBuilder is minimal.
*
* Note: calling toString() will force the entire string to be loaded in memory, use toWriter()
* if you need to avoid this.
*
*
This class is not multi thread safe.
*
* @author Cedric Beust
* @since Nov 9, 2012
*/
public class FileStringBuffer implements IBuffer {
private static int MAX = 100000;
private static final boolean VERBOSE = RuntimeBehavior.verboseMode();
private static final Logger LOGGER = Logger.getLogger(FileStringBuffer.class);
private File m_file;
private StringBuilder m_sb = new StringBuilder();
private final int m_maxCharacters;
public FileStringBuffer() {
this(MAX);
}
public FileStringBuffer(int maxCharacters) {
m_maxCharacters = maxCharacters;
}
@Override
public FileStringBuffer append(CharSequence s) {
if (s == null) {
throw new IllegalArgumentException(
"CharSequence (Argument 0 of FileStringBuffer#append) should not be null");
}
// m_sb.append(s);
if (m_sb.length() > m_maxCharacters) {
flushToFile();
}
if (s.length() < MAX) {
// Small string, add it to our internal buffer
m_sb.append(s);
} else {
// Big string, add it to the temporary file directly
flushToFile();
try (FileWriter writer = new FileWriter(m_file, true /* append */)) {
copy(new StringReader(s.toString()), writer);
} catch (IOException e) {
LOGGER.error(e.getMessage(), e);
}
}
return this;
}
@Override
public void toWriter(Writer fw) {
if (fw == null) {
throw new IllegalArgumentException(
"Writer (Argument 0 of FileStringBuffer#toWriter) should not be null");
}
try {
BufferedWriter bw = new BufferedWriter(fw);
if (m_file == null) {
bw.write(m_sb.toString());
bw.close();
} else {
flushToFile();
try (FileReader reader = new FileReader(m_file)) {
copy(reader, bw);
}
bw.flush();
}
} catch (IOException e) {
LOGGER.error(e.getMessage(), e);
}
}
private static void copy(Reader input, Writer output) throws IOException {
char[] buf = new char[MAX];
while (true) {
int length = input.read(buf);
if (length < 0) break;
output.write(buf, 0, length);
}
}
private void flushToFile() {
if (m_sb.length() == 0) return;
if (m_file == null) {
try {
m_file = File.createTempFile("testng", "fileStringBuffer");
m_file.deleteOnExit();
p("Created temp file " + m_file);
} catch (IOException e) {
LOGGER.error(e.getMessage(), e);
}
}
p("Size " + m_sb.length() + ", flushing to " + m_file);
try (FileWriter fw = new FileWriter(m_file, true /* append */)) {
fw.append(m_sb);
} catch (IOException e) {
e.printStackTrace();
}
m_sb = new StringBuilder();
}
private static void p(String s) {
if (VERBOSE) {
LOGGER.info("[FileStringBuffer] " + s);
}
}
@Override
public String toString() {
String result = null;
if (m_file != null) {
flushToFile();
try {
result = Files.readFile(m_file);
} catch (IOException e) {
LOGGER.error(e.getMessage(), e);
}
} else {
result = m_sb.toString();
}
return result;
}
}