// This file is part of PleoCommand:
// Interactively control Pleo with psychobiological parameters
//
// Copyright (C) 2010 Oliver Hoffmann - Hoffmann_Oliver@gmx.de
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// This program 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 General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Boston, USA.
package pleocmd.pipe.in;
import java.io.DataInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.Arrays;
import javax.swing.filechooser.FileFilter;
import javax.swing.filechooser.FileNameExtensionFilter;
import pleocmd.Log;
import pleocmd.RunnableWithArgument;
import pleocmd.StringManip;
import pleocmd.cfg.ConfigEnum;
import pleocmd.cfg.ConfigPath;
import pleocmd.cfg.ConfigPath.PathType;
import pleocmd.exc.ConfigurationException;
import pleocmd.exc.FormatException;
import pleocmd.exc.InputException;
import pleocmd.exc.InternalException;
import pleocmd.itfc.gui.dse.DataFileBinaryDialog;
import pleocmd.itfc.gui.dse.DataFileEditDialog;
import pleocmd.pipe.data.Data;
import pleocmd.pipe.out.FileOutput;
import pleocmd.pipe.out.Output;
public final class FileInput extends Input { // NO_UCD
private final ConfigPath cfgFile;
private final ConfigEnum<ReadType> cfgType;
private DataInputStream in;
public FileInput() {
addConfig(cfgFile = new ConfigPath("File", PathType.FileForReading));
addConfig(cfgType = new ConfigEnum<ReadType>(ReadType.class));
cfgFile.setFileFilter(Arrays.asList(new FileFilter[] {
new FileNameExtensionFilter("ASCII-Textfiles", "txt"),
new FileNameExtensionFilter("Pleo ASCII Data", "pad"),
new FileNameExtensionFilter("Pleo Binary Data", "pbd") }));
cfgFile.setModifyFile(new RunnableWithArgument() {
@Override
public Object run(final Object... args) {
final String fileName = (String) args[0];
if (fileName.endsWith(".pbd"))
new DataFileBinaryDialog(new File(fileName));
else
new DataFileEditDialog(new File(fileName));
return null;
}
});
cfgFile.setChangingContent(new RunnableWithArgument() {
@Override
public Object run(final Object... args) {
final String path = (String) args[0];
switch (getCfgType().getEnumGUI()) {
case Ascii:
if (path.endsWith(".pbd"))
getCfgType().setEnumGUI(ReadType.Binary);
break;
case Binary:
if (!path.endsWith(".pbd"))
getCfgType().setEnumGUI(ReadType.Ascii);
break;
}
return null;
}
});
cfgType.setChangingContent(new RunnableWithArgument() {
@Override
public Object run(final Object... args) {
final String path = getCfgFile().getContentGUI().getPath();
switch (ReadType.valueOf((String) args[0])) {
case Ascii:
if (path.endsWith(".pbd")) getCfgFile().clearContentGUI();
break;
case Binary:
if (!path.endsWith(".pbd")) getCfgFile().clearContentGUI();
break;
}
return null;
}
});
constructed();
}
public FileInput(final File file, final ReadType type)
throws ConfigurationException {
this();
cfgFile.setContent(file);
cfgType.setEnum(type);
}
@Override
protected void init0() throws IOException {
Log.detail("Opening file '%s' for input", cfgFile.getContent());
in = new DataInputStream(new FileInputStream(cfgFile.getContent()));
}
@Override
protected void close0() throws IOException {
Log.detail("Closing file '%s'", cfgFile.getContent());
in.close();
in = null;
}
@Override
public String getOutputDescription() {
return "";
}
@Override
protected String getShortConfigDescr0() {
return String.format("\"%s\"", cfgFile.getContent().getName());
}
@Override
protected Data readData0() throws InputException, IOException {
if (in.available() <= 0) {
Log.info("End Of File in File-Input");
return null;
}
switch (cfgType.getEnum()) {
case Ascii:
try {
final Data data = Data.createFromAscii(in);
if (Log.canLogDetail())
Log.detail("<html>Read from file: %s",
StringManip.printSyntaxHighlightedAscii(data));
return data;
} catch (final FormatException e) {
throw new InputException(this, false, e,
"Cannot read from file");
}
case Binary:
try {
final Data data = Data.createFromBinary(in);
if (Log.canLogDetail())
Log.detail("<html>Read from file: %s",
StringManip.printSyntaxHighlightedBinary(data));
return data;
} catch (final FormatException e) {
throw new InputException(this, false, e,
"Cannot read from file");
}
default:
throw new InternalException(cfgType.getEnum());
}
}
public static String help(final HelpKind kind) {
switch (kind) {
case Name:
return "File Input";
case Description:
return "Reads Data blocks from external files";
case Config1:
return "Path to an external file from which commands should "
+ "be read in either ASCII or binary form";
case Config2:
return "'Ascii' if Data blocks are in ASCII format or\n"
+ " 'Binary' if Data blocks should be treated as binary";
default:
return null;
}
}
@Override
public String isConfigurationSane() {
final File file = cfgFile.getContent();
if (isConnected())
for (final Output out : getPipe().getOutputList())
if (out instanceof FileOutput
&& ((FileOutput) out).getCfgFile().getContent()
.equals(file))
return String
.format("Same file has already been specified by '%s'",
out);
return file.canRead() ? null : String.format("Cannot read from '%s'",
cfgFile.getContent());
}
@Override
protected int getVisualizeDataSetCount() {
return 0;
}
public ConfigPath getCfgFile() {
return cfgFile;
}
protected ConfigEnum<ReadType> getCfgType() {
return cfgType;
}
}