package com.twasyl.slideshowfx.engine;
import com.twasyl.slideshowfx.utils.PlatformHelper;
import com.twasyl.slideshowfx.utils.io.DefaultCharsetReader;
import com.twasyl.slideshowfx.utils.io.DefaultCharsetWriter;
import java.beans.PropertyChangeListener;
import java.beans.PropertyChangeSupport;
import java.io.*;
/**
* This class implements {@link IEngine} in order to define base treatments used by all engine defined in SlideshowFX.
*
* @author Thierry Wasylczenko
*/
public abstract class AbstractEngine<T extends IConfiguration> implements IEngine<T> {
protected final PropertyChangeSupport propertyChangeSupport = new PropertyChangeSupport(this);
protected final String configurationFilename;
protected final String archiveExtension;
protected File archiveFile;
protected File workingDirectory;
protected T configuration;
/**
* Creates an instance of the engine and set the archiveExtension all archive files of this engine must have.
* For example, the archiveExtension for presentations' archives is {@code sfx} and for template's <code>sfxt</code>.
*
* @param archiveExtension The archiveExtension for each archive files of this engine.
* @param configurationFilename The name of the configuration file, depending the implementation.
*/
protected AbstractEngine(String archiveExtension, String configurationFilename) {
this.archiveExtension = archiveExtension;
this.configurationFilename = configurationFilename;
}
@Override public String getConfigurationFilename() { return this.configurationFilename; }
@Override public String getArchiveExtension() { return this.archiveExtension; }
@Override public File getArchive() { return this.archiveFile; }
@Override public void setArchive(File file) {
final File oldFile = this.archiveFile;
this.archiveFile = file;
PlatformHelper.run(() -> this.propertyChangeSupport.firePropertyChange("archiveFile", oldFile, this.archiveFile));
}
@Override
public File generateWorkingDirectory() {
return new File(System.getProperty("java.io.tmpdir"), "sfx-" + System.currentTimeMillis());
}
@Override public File getWorkingDirectory() { return this.workingDirectory; }
@Override public void setWorkingDirectory(File workingDirectory) { this.workingDirectory = workingDirectory; }
@Override
public String relativizeFromWorkingDirectory(File file) throws NullPointerException {
if(file == null) throw new NullPointerException("The given file can not be null");
if(getWorkingDirectory() == null) throw new NullPointerException("The working directory is null");
return getWorkingDirectory().toPath()
.relativize(file.toPath())
.toString().replace(File.separator, "/");
}
@Override
public T readConfiguration() throws NullPointerException, IOException, IllegalAccessException {
if(getWorkingDirectory() == null) throw new NullPointerException("The working directory is null");
if(this.configurationFilename == null) throw new NullPointerException("The configuration filename can not be null");
if(this.configurationFilename.isEmpty()) throw new IllegalArgumentException("The configuration filename can not be empty");
final File configurationFile = new File(getWorkingDirectory(), this.configurationFilename);
return this.readConfiguration(configurationFile);
}
@Override
public T readConfiguration(File configurationFile) throws NullPointerException, IllegalArgumentException, IOException, IllegalAccessException {
if(getWorkingDirectory() == null) throw new NullPointerException("The working directory is null");
if(configurationFile == null) throw new NullPointerException("The configuration file can not be null");
if(!configurationFile.exists()) throw new FileNotFoundException("The configuration file does not exist");
if(!configurationFile.canRead()) throw new IllegalAccessException("The configuration file can not be read");
final Reader reader = new DefaultCharsetReader(configurationFile);
return this.readConfiguration(reader);
}
@Override
public void writeConfiguration() throws NullPointerException, IOException {
if(getWorkingDirectory() == null) throw new NullPointerException("The working directory is null");
if(this.configurationFilename == null) throw new NullPointerException("The configuration filename can not be null");
if(this.configurationFilename.isEmpty()) throw new IllegalArgumentException("The configuration filename can not be empty");
final File configurationFile = new File(getWorkingDirectory(), this.configurationFilename);
this.writeConfiguration(configurationFile);
}
@Override
public void writeConfiguration(File configurationFile) throws NullPointerException, IOException {
if(getWorkingDirectory() == null) throw new NullPointerException("The working directory is null");
if(configurationFile == null) throw new NullPointerException("The configuration file can not be null");
final DefaultCharsetWriter writer = new DefaultCharsetWriter(configurationFile);
this.writeConfiguration(writer);
}
@Override public T getConfiguration() { return this.configuration; }
@Override public void setConfiguration(T configuration) { this.configuration = configuration; }
@Override public void loadArchive() throws IllegalArgumentException, NullPointerException, IOException, IllegalAccessException {
this.loadArchive(getArchive());
}
@Override public synchronized void saveArchive() throws IllegalArgumentException, IOException {
this.saveArchive(getArchive());
}
public void addPropertyChangeListener(PropertyChangeListener listener) {
this.propertyChangeSupport.addPropertyChangeListener(listener);
}
public void removePropertyChangeListener(PropertyChangeListener listener) {
this.propertyChangeSupport.removePropertyChangeListener(listener);
}
public void addPropertyChangeListener(String propertyName, PropertyChangeListener listener) {
this.propertyChangeSupport.addPropertyChangeListener(propertyName, listener);
}
public void removePropertyChangeListener(String propertyName, PropertyChangeListener listener) {
this.propertyChangeSupport.removePropertyChangeListener(propertyName, listener);
}
}