/**
*
*/
package fr.cedrik.email.fs;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.Writer;
import java.util.Iterator;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import fr.cedrik.email.FoldersList;
import fr.cedrik.email.spi.Message;
import fr.cedrik.util.Charsets;
/**
* Usage:
* <ul><li>{@link #openFolder(String)}</li>
* <li>{@link #openFile(String, Message)}</li>
* <li>{@link #write(Message, Iterator)}</li>
* <li>{@link #closeFile(Message)} (in {@code finally} block!)</li>
* <li>{@link #closeFolder()} (in {@code finally} block!)</li></ul>
*
* @author Cédrik LIME
*/
public abstract class BaseZipWriter {
protected final Logger logger = LoggerFactory.getLogger(this.getClass());
protected ZipOutputStream outStream = null;
protected Writer outWriter = null;
protected ZipEntry currentEntry = null;
protected String baseName = "";
public BaseZipWriter(ZipOutputStream out, String baseName) {
this.outStream = out;
baseName = StringUtils.defaultString(baseName);
if ( ! baseName.isEmpty() && ! baseName.endsWith("/")) {
baseName += '/';
}
this.baseName = baseName;
}
public abstract void openFolder(String folderChainStr) throws IOException;
public abstract void openFile(String folderChainStr, Message message) throws IOException;
protected void newZipEntry(String folderChainStr, Message message) throws IOException {
currentEntry = new ZipEntry(computeZipMailFileName(folderChainStr, message));
if (message != null && message.getDate() != null) {
currentEntry.setTime(message.getDate().getTime());
}
outStream.putNextEntry(currentEntry);
outWriter = new BufferedWriter(new OutputStreamWriter(outStream, Charsets.US_ASCII), 32*1024);
}
// protected abstract ZipEntry getMBoxFile(Message message);
/**
* You can use {@link BaseZipWriter#computeZipFolderName(Folder, FoldersList, String)} for base folder handling
*/
protected abstract String computeZipMailFileName(String folderChainStr, Message message);
public final void write(Message message, Iterator<String> mime) throws IOException {
logger.debug("Writing message {}", message);
writeMIME(outWriter, message, mime);
}
public void flush() throws IOException {
if (outWriter != null) {
outWriter.flush();
}
}
public abstract void closeFile(Message message) throws IOException;
public abstract void closeFolder() throws IOException;
protected void closeZipEntry() throws IOException {
if (outWriter != null) {
outWriter.flush(); // very important in order to not corrupt the ZIP stream!
}
// IOUtils.closeQuietly(outWriter);// Do not close stream, it is the caller's responsability
outStream.closeEntry();
currentEntry = null;
}
protected abstract void writeMIME(Writer mbox, Message message, Iterator<String> mime) throws IOException;//FIXME replace Message with "extraHeaders"?
/**
* @return RFC-compliant new-line char
*/
protected String newLine() {
return "\n";
}
/**
* @return RFC-compliant new-line char
*/
protected Writer newLine(Writer out) throws IOException {
return out.append(newLine());
}
}