org.opencms.importexport.CmsExportHelper Maven / Gradle / Ivy
Show all versions of opencms-test Show documentation
/*
* This library is part of OpenCms -
* the Open Source Content Management System
*
* Copyright (c) Alkacon Software GmbH & Co. KG (http://www.alkacon.com)
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* For further information about Alkacon Software, please see the
* company website: http://www.alkacon.com
*
* For further information about OpenCms, please see the
* project website: http://www.opencms.org
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
package org.opencms.importexport;
import org.opencms.configuration.CmsConfigurationManager;
import org.opencms.file.CmsFile;
import org.opencms.main.OpenCms;
import org.opencms.util.CmsFileUtil;
import org.opencms.util.CmsXmlSaxWriter;
import java.io.File;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.io.StringWriter;
import java.io.Writer;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;
import org.dom4j.io.SAXWriter;
import org.xml.sax.SAXException;
/**
* Wrapper to write exported OpenCms resources either to a .ZIP file or to the file system.
*
* @since 7.5.1
*/
public class CmsExportHelper {
/** Length that can be safely written to ZIP output. */
private static final int SUB_LENGTH = 4096;
/** The main export path. */
private String m_exportPath;
/** The export ZIP stream to write resources to. */
private ZipOutputStream m_exportZipStream;
/** Indicates if the resources are exported in one export .ZIP file or as individual files. */
private boolean m_isExportAsFiles;
/** The SAX writer for the Manifest file. */
private SAXWriter m_saxWriter;
/**
* Creates a new export helper.
*
* @param exportPath the export path
* @param exportAsFiles indicates if the resources should be exported as individual files or in one big ZIP file
* @param validateXml indicates of the manifest.xml should be validated
*
* @throws SAXException in case of issues creating the manifest.xml
* @throws IOException in case of file access issues
*/
public CmsExportHelper(String exportPath, boolean exportAsFiles, boolean validateXml)
throws SAXException, IOException {
m_exportPath = exportPath;
m_isExportAsFiles = exportAsFiles;
removeOldExport(exportPath);
Writer writer;
if (m_isExportAsFiles) {
m_exportPath = m_exportPath + "/";
// write to file system directly
String fileName = getRfsFileName(CmsImportExportManager.EXPORT_MANIFEST);
File rfsFile = new File(fileName);
rfsFile.getParentFile().mkdirs();
rfsFile.createNewFile();
writer = new FileWriter(rfsFile);
} else {
// create the export ZIP stream
m_exportZipStream = new ZipOutputStream(new FileOutputStream(m_exportPath));
// delegate writing to a String writer
writer = new StringWriter(SUB_LENGTH);
}
// generate the SAX XML writer
CmsXmlSaxWriter saxHandler = new CmsXmlSaxWriter(writer, OpenCms.getSystemInfo().getDefaultEncoding());
saxHandler.setEscapeXml(true);
saxHandler.setEscapeUnknownChars(true);
// start the document
saxHandler.startDocument();
// set the doctype if needed
if (validateXml) {
saxHandler.startDTD(
CmsImportExportManager.N_EXPORT,
null,
CmsConfigurationManager.DEFAULT_DTD_PREFIX + CmsImportVersion7.DTD_FILENAME);
saxHandler.endDTD();
}
// initialize the dom4j writer object
m_saxWriter = new SAXWriter(saxHandler, saxHandler);
}
/**
* Returns the SAX writer for the Manifest file.
*
* @return the SAX writer for the Manifest file
*/
public SAXWriter getSaxWriter() {
return m_saxWriter;
}
/**
* Writes a single OpenCms VFS file to the export.
*
* @param file the OpenCms VFS file to write
* @param name the name of the file in the export
*
* @throws IOException in case of file access issues
*/
public void writeFile(CmsFile file, String name) throws IOException {
if (m_isExportAsFiles) {
writeFile2Rfs(file, name);
} else {
writeFile2Zip(file, name);
}
}
/**
* Writes the OpenCms manifest.xml file to the export.
*
* @param xmlSaxWriter the SAX writer to use
*
* @throws SAXException in case of issues creating the manifest.xml
* @throws IOException in case of file access issues
*/
public void writeManifest(CmsXmlSaxWriter xmlSaxWriter) throws IOException, SAXException {
if (m_isExportAsFiles) {
writeManifest2Rfs(xmlSaxWriter);
} else {
writeManifest2Zip(xmlSaxWriter);
}
}
/**
* Returns the RFS file name for the given OpenCms VFS file name.
*
* @param name the OpenCms VFS file name
*
* @return the RFS file name for the given OpenCms VFS file name
*/
protected String getRfsFileName(String name) {
return m_exportPath + name;
}
/**
* Removes the old export output, which may be an existing file or directory.
*
* @param exportPath the export output path
*/
protected void removeOldExport(String exportPath) {
File output = new File(exportPath);
if (output.exists()) {
// the output already exists
if (output.isDirectory()) {
// purge the complete directory
CmsFileUtil.purgeDirectory(output);
} else {
// remove the existing file
if (m_isExportAsFiles) {
// in case we write to a file we can just overwrite,
// but for a folder we must remove an existing file
output.delete();
}
}
}
}
/**
* Writes a single OpenCms VFS file to the RFS export.
*
* @param file the OpenCms VFS file to write
* @param name the name of the file in the export
*
* @throws IOException in case of file access issues
*/
protected void writeFile2Rfs(CmsFile file, String name) throws IOException {
String fileName = getRfsFileName(name);
File rfsFile = new File(fileName);
if (!rfsFile.getParentFile().exists()) {
rfsFile.getParentFile().mkdirs();
}
rfsFile.createNewFile();
FileOutputStream rfsFileOut = new FileOutputStream(rfsFile);
rfsFileOut.write(file.getContents());
rfsFileOut.close();
}
/**
* Writes a single OpenCms VFS file to the ZIP export.
*
* @param file the OpenCms VFS file to write
* @param name the name of the file in the export
*
* @throws IOException in case of file access issues
*/
protected void writeFile2Zip(CmsFile file, String name) throws IOException {
ZipEntry entry = new ZipEntry(name);
// save the time of the last modification in the zip
entry.setTime(file.getDateLastModified());
m_exportZipStream.putNextEntry(entry);
m_exportZipStream.write(file.getContents());
m_exportZipStream.closeEntry();
}
/**
* Writes the OpenCms manifest.xml file to the RFS export.
*
* In case of the RFS export the file is directly written to a file output stream,
* so calling this method just closes the XML and finishes the stream.
*
* @param xmlSaxWriter the SAX writer to use
*
* @throws SAXException in case of issues creating the manifest.xml
* @throws IOException in case of issues closing the file writer
*/
protected void writeManifest2Rfs(CmsXmlSaxWriter xmlSaxWriter) throws SAXException, IOException {
// close the document - this will also trigger flushing the contents to the file system
xmlSaxWriter.endDocument();
xmlSaxWriter.getWriter().close();
}
/**
* Writes the OpenCms manifest.xml file to the ZIP export.
*
* In case of the ZIP export the manifest is written to an internal StringBuffer
* first, which is then stored in the ZIP file when this method is called.
*
* @param xmlSaxWriter the SAX writer to use
*
* @throws SAXException in case of issues creating the manifest.xml
* @throws IOException in case of file access issues
*/
protected void writeManifest2Zip(CmsXmlSaxWriter xmlSaxWriter) throws IOException, SAXException {
// close the document
xmlSaxWriter.endDocument();
xmlSaxWriter.getWriter().close();
// create ZIP entry for the manifest XML document
ZipEntry entry = new ZipEntry(CmsImportExportManager.EXPORT_MANIFEST);
m_exportZipStream.putNextEntry(entry);
// complex substring operation is required to ensure handling for very large export manifest files
StringBuffer result = ((StringWriter)xmlSaxWriter.getWriter()).getBuffer();
int steps = result.length() / SUB_LENGTH;
int rest = result.length() % SUB_LENGTH;
int pos = 0;
for (int i = 0; i < steps; i++) {
String sub = result.substring(pos, pos + SUB_LENGTH);
m_exportZipStream.write(sub.getBytes(OpenCms.getSystemInfo().getDefaultEncoding()));
pos += SUB_LENGTH;
}
if (rest > 0) {
String sub = result.substring(pos, pos + rest);
m_exportZipStream.write(sub.getBytes(OpenCms.getSystemInfo().getDefaultEncoding()));
}
// close the zip entry for the manifest XML document
m_exportZipStream.closeEntry();
// finally close the zip stream
m_exportZipStream.close();
}
}