/*
* Created on May 17, 2006
*/
package com.openedit.modules.update;
import java.io.File;
import java.io.FileOutputStream;
import java.io.FilenameFilter;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import com.openedit.OpenEditException;
import com.openedit.page.manage.PageManager;
import com.openedit.util.FileUtils;
import com.openedit.util.PageZipUtil;
import com.openedit.util.ZipUtil;
public class Backup
{
protected PageManager fieldPageManager;
protected SimpleDateFormat fieldFormat = new SimpleDateFormat("yyyy_MM_dd_HH_mm_ss");
protected File fieldRoot;
protected String fieldIncludePath = "/";
protected FileUtils fieldUtils = new FileUtils();
protected List fieldExcludes = new ArrayList();
private static final Log log = LogFactory.getLog(Backup.class);
public PageManager getPageManager()
{
return fieldPageManager;
}
public void setPageManager(PageManager inPageManager)
{
fieldPageManager = inPageManager;
}
protected File backupCurrentSite(String inName) throws OpenEditException
{
PageZipUtil zip = new PageZipUtil(getPageManager());
zip.setRoot(getRoot());
for (Iterator iter = getExcludes().iterator(); iter.hasNext();)
{
String exclude = (String) iter.next();
zip.addExclude(exclude);
}
// zip.addExclude("*/WEB-INF/*");
// zip.addExclude("*/.versions/*");
// zip.addExclude("*/WEB-INF/trash/*");
// zip.addExclude("*/WEB-INF/tmp/*");
// zip.addExclude("*/WEB-INF/log*");
inName = inName.replace(" ", "_");
inName = inName.replace("/", "_");
inName = inName.replace("\\", "_");
String id = fieldFormat.format(new Date() ) + "_" + inName;
String outpath = "/WEB-INF/versions/" + id + ".zip";
zip.addExclude(outpath);
File out = new File( getRoot() , outpath );
log.info("Backing up " + out);
try
{
out.getParentFile().mkdirs();
FileOutputStream stream = new FileOutputStream(out);
try
{
zip.zipFile(getIncludePath(), stream );
}
finally
{
FileUtils.safeClose(stream);
}
return out;
}
catch ( IOException ex)
{
throw new OpenEditException(ex);
}
}
public File getRoot()
{
return fieldRoot;
}
public void setRoot(File inRoot)
{
fieldRoot = inRoot;
}
public List listSiteVersions()
{
File verdir = new File( getRoot() , "WEB-INF/versions");
verdir.mkdirs();
File[] children = verdir.listFiles(new FilenameFilter() {
public boolean accept(File inDir, String inName)
{
return inName.endsWith(".zip");
}
});
List list = new ArrayList();
if ( children != null)
{
for (int i = 0; i < children.length; i++)
{
File child = children[i];
list.add(child);
}
}
Collections.sort(list);
return list;
}
public File loadVersion(String inName)
{
List list = listSiteVersions();
for (Iterator iter = list.iterator(); iter.hasNext();)
{
File version= (File) iter.next();
if ( version.getName().equals( inName ))
{
return version;
}
}
return null;
}
protected void restoreBackup(File inVersion) throws OpenEditException
{
log.info("Restoring " + inVersion.getName() );
File tmp = null;
try
{
tmp = new File( getRoot(),"WEB-INF/trash/new" + fieldFormat.format(new Date() ));
tmp.mkdirs();
ZipUtil utils = new ZipUtil();
//unzip the zip file in a tmp directory
utils.unzip(inVersion,tmp);
}
catch (IOException ex )
{
throw new OpenEditException("No harm done", ex);
}
File old = new File( getRoot(),"WEB-INF/trash/old" + fieldFormat.format(new Date() ));
try
{
replaceDirectories(tmp,getRoot(),old);
}
catch (IOException ex )
{
throw new OpenEditException( ex );
}
// try
// {
// File tmpold = null;
// }
// finally
// {
// if( !tmp.renameTo(getRoot()) )
// {
// //copy it
// try
// {
// log.error("Could not rename");
// //org.apache.commons.io.FileUtils.copyFile(tmp, getRoot(), true);
// new FileUtils().copyFiles(tmp, getRoot() );
// }
// catch ( IOException ex)
// {
// throw new OpenEditException(ex);
// }
// }
// //bring back the versions
// File versions = new File( tmpold , "WEB-INF/versions");
// File newversions = new File( getRoot(), "WEB-INF/versions");
// versions.renameTo(newversions);
// }
}
/**
* This method does a replacement of top level directories.
* One exception is the WEB-INF directory that it will go into
* @param inNewDirs
* @param inRoot
* @param inSubPath
* @param inOldDirectory
* @throws IOException
*/
protected void replaceDirectories(File inNewDirs, File inRoot, File inOldDirectory ) throws IOException
{
//move the existing content to tmp2
// tmpold = File.createTempFile("upgradeold", "");
// tmpold.delete();
// tmpold.mkdirs();
File[] children = inNewDirs.listFiles();
for (int i = 0; i < children.length; i++)
{
File child = children[i];
File existing = new File( inRoot, child.getName() );
if( existing.exists() )
{
//Then move it into away
if( child.getName().equals("WEB-INF"))
{
//replaceDirectories(child, existing, inOldDirectory);
continue;
}
else
{
if( existing.isDirectory() )
{
fieldUtils.move(existing, new File( inOldDirectory, existing.getName() ));
}
else
{
//this is an existing file in the inNewDirs directory
File backup = new File( inOldDirectory, child.getName() );
if( !existing.renameTo(backup) )
{
throw new IOException("Could not move " + existing.getPath() + " to " + backup.getPath());
}
}
}
}
//Now replace it
fieldUtils.move(child, new File( getRoot(), child.getName() ) );
//child.renameTo(new File( getRoot(), child.getName() ));
}
//TODO: Do this in smaller parts so we can exclude WEB-INF/logs/
// if ( !getRoot().renameTo(tmpold) )
// {
// log.info("Had to copy manually");
// FileUtils fu = new FileUtils();
// fu.copyFiles(getRoot(), tmpold );
// fu.deleteAll(getRoot());
// }
// File[] all = tmpold.listFiles();
// if ( all.length == 0)
// {
// throw new OpenEditException("Problem: Could not move entire existing site. Some files moved to: " + tmpold.getPath());
// }
}
public String getIncludePath()
{
return fieldIncludePath;
}
public void setIncludePath(String inIncludePath)
{
fieldIncludePath = inIncludePath;
}
public List getExcludes()
{
if (fieldExcludes == null)
{
fieldExcludes = new ArrayList();
}
return fieldExcludes;
}
public void setExcludes(List inExcludes)
{
this.fieldExcludes = inExcludes;
}
public void addExclude(String inExclude)
{
getExcludes().add(inExclude);
}
}