package org.exist.backup; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.OutputStream; import java.io.StringWriter; import java.io.Writer; import java.util.zip.ZipEntry; import java.util.zip.ZipOutputStream; import java.util.Properties; /** * Implementation of BackupWriter that writes to a zip file. */ public class ZipWriter implements BackupWriter { private String currentPath; private ZipOutputStream out; private StringWriter contents; private boolean dataWritten = false; public ZipWriter(String zipFile, String collection) throws IOException { this(new File(zipFile), collection); } public ZipWriter(File zipFile, String collection) throws IOException { out = new ZipOutputStream(new FileOutputStream(zipFile)); currentPath = collection; } public Writer newContents() throws IOException { contents = new StringWriter(); return contents; } public void closeContents() throws IOException { ZipEntry entry = new ZipEntry(mkRelative(currentPath) + "/__contents__.xml"); out.putNextEntry(entry); out.write(contents.toString().getBytes("UTF-8")); out.closeEntry(); dataWritten = true; } public OutputStream newEntry(String name) throws IOException { ZipEntry entry = new ZipEntry(mkRelative(currentPath) + '/' + name); out.putNextEntry(entry); dataWritten = true; return out; } public void closeEntry() throws IOException { out.closeEntry(); } public void newCollection(String name) { if (name.startsWith("/")) currentPath = name; else currentPath = currentPath + '/' + name; } public void closeCollection() { int p = currentPath.lastIndexOf('/'); if (p > 0) currentPath = currentPath.substring(0, p); } public void close() throws IOException { out.close(); } public void setProperties(Properties properties) throws IOException { if (dataWritten) throw new IOException("Backup properties need to be set before any backup data is written"); ZipEntry entry = new ZipEntry("backup.properties"); out.putNextEntry(entry); properties.store(out, "Backup properties"); out.closeEntry(); } private String mkRelative(String path) { if (path.length() > 0 && path.charAt(0) == '/') return path.substring(1); return path; } }