it.tidalwave.netbeans.filesystem.sync.impl.FileSystemSynchronizerImpl Maven / Gradle / Ivy
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package it.tidalwave.netbeans.filesystem.sync.impl;
import it.tidalwave.netbeans.filesystem.sync.FileSystemSynchronizer;
import java.beans.PropertyChangeListener;
import java.beans.PropertyChangeSupport;
import java.io.IOException;
import java.util.SortedMap;
import java.util.SortedSet;
import java.util.TreeMap;
import java.util.TreeSet;
import javax.annotation.Nonnegative;
import javax.annotation.Nonnull;
import org.openide.filesystems.FileObject;
import org.openide.filesystems.FileStateInvalidException;
import org.openide.filesystems.FileSystem;
import org.openide.util.Parameters;
/**
*
* @author fritz
*/
public class FileSystemSynchronizerImpl implements FileSystemSynchronizer
{
protected int fileCount;
protected int processedFileCount;
public static final String PROP_FILECOUNT = "fileCount";
public static final String PROP_PROCESSEDFILECOUNT = "processedFileCount";
private final PropertyChangeSupport propertyChangeSupport = new PropertyChangeSupport(this);
/***************************************************************************
*
**************************************************************************/
public void synchronize (@Nonnull FileObject sourceFolder,
@Nonnull FileObject targetFolder,
@Nonnull Strategy strategy)
throws IOException
{
Parameters.notNull("source", sourceFolder);
Parameters.notNull("target", targetFolder);
Parameters.notNull("strategy", strategy);
final SortedMap sourceFiles = findFileObjectsRecursively(sourceFolder, sourceFolder);
final SortedMap targetFiles = findFileObjectsRecursively(targetFolder, targetFolder);
final SortedSet paths = new TreeSet();
paths.addAll(sourceFiles.keySet());
paths.addAll(targetFiles.keySet());
setFileCount(paths.size());
for (final String path : paths)
{
final FileObject sourceFile = sourceFiles.get(path);
final FileObject targetFile = targetFiles.get(path);
final FileObject sourceFileParent = findFolder(sourceFolder, path);
final FileObject targetFileParent = findFolder(targetFolder, path);
final Context context = new Context()
{
public FileObject getSourceFolder()
{
return sourceFileParent;
}
public FileObject getTargetFolder()
{
return targetFileParent;
}
};
strategy.synchronize(sourceFile, targetFile, context);
synchronized(this)
{
setProcessedFileCount(getProcessedFileCount() + 1);
}
}
}
/***************************************************************************
*
**************************************************************************/
public int getFileCount()
{
return fileCount;
}
/***************************************************************************
*
**************************************************************************/
@Nonnull
private FileObject findFolder (@Nonnull final FileObject folder,
@Nonnull final String path)
throws FileStateInvalidException
{
assert folder != null;
assert path != null;
final FileSystem fileSystem = folder.getFileSystem();
return fileSystem.findResource(folder.getPath() + "/" + path);
}
/***************************************************************************
*
**************************************************************************/
private void setFileCount (@Nonnegative final int fileCount)
{
int oldFileCount = this.fileCount;
this.fileCount = fileCount;
propertyChangeSupport.firePropertyChange(PROP_FILECOUNT, oldFileCount, fileCount);
}
/***************************************************************************
*
**************************************************************************/
public int getProcessedFileCount()
{
return processedFileCount;
}
/***************************************************************************
*
**************************************************************************/
private void setProcessedFileCount (@Nonnegative final int processedFileCount)
{
int oldProcessedFileCount = this.processedFileCount;
this.processedFileCount = processedFileCount;
propertyChangeSupport.firePropertyChange(PROP_PROCESSEDFILECOUNT, oldProcessedFileCount, processedFileCount);
}
/***************************************************************************
*
**************************************************************************/
public void addPropertyChangeListener (@Nonnull final PropertyChangeListener listener)
{
Parameters.notNull("listener", listener);
propertyChangeSupport.addPropertyChangeListener(listener);
}
/***************************************************************************
*
**************************************************************************/
public void removePropertyChangeListener (@Nonnull final PropertyChangeListener listener)
{
Parameters.notNull("listener", listener);
propertyChangeSupport.removePropertyChangeListener(listener);
}
/***************************************************************************
*
**************************************************************************/
@Nonnull
private SortedMap findFileObjectsRecursively (@Nonnull final FileObject baseFolder,
@Nonnull final FileObject folder)
{
assert baseFolder != null;
assert folder != null;
final SortedMap result = new TreeMap();
final String pathPrefix = baseFolder.getPath();
for (final FileObject fileObject : folder.getChildren())
{
if (fileObject.isFolder())
{
String path = fileObject.getPath();
assert path.startsWith(pathPrefix);
path = path.substring(pathPrefix.length());
result.put(path, fileObject);
}
else
{
result.putAll(findFileObjectsRecursively(baseFolder, fileObject));
}
}
return result;
}
}