Commit 4b3e80c7 authored by Vincent van Beveren's avatar Vincent van Beveren

fixed issue in filename with export

added backup feature
parent c936dda7
......@@ -75,12 +75,11 @@ public class I2CDataSource extends DataSource {
i2c.open();
i2c.i2cWrite(_addr, out);
} catch (IOException e) {
e.printStackTrace();
throw new RuntimeException("Failed to write at offset="+ off + ", " + data.length + " byte(s)", e);
} finally {
try {
i2c.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
......
......@@ -18,7 +18,10 @@
package nl.nikhef.safaripark;
import java.awt.Component;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileWriter;
......@@ -30,7 +33,9 @@ import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.swing.Action;
import javax.swing.BorderFactory;
......@@ -41,6 +46,7 @@ import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JRadioButton;
import javax.swing.filechooser.FileNameExtensionFilter;
import nl.nikhef.safaripark.devmgr.BaySelectionListener;
import nl.nikhef.safaripark.extra.BaseMessage;
......@@ -58,7 +64,11 @@ public class ModuleManager implements BaySelectionListener
{
private Action _binExport;
private Action _backup;
private Action _restore;
private JFileChooser _dirChooser;
private JFileChooser _backupChooser;
private JRadioButton _binary;
private JRadioButton _plainhex;
private JRadioButton _extendedhex;
......@@ -70,11 +80,19 @@ public class ModuleManager implements BaySelectionListener
private AppContext _appCtx;
private Module _selectedMod;
public ModuleManager(Action binExport, AppContext appCtx)
public ModuleManager(Action binExport, Action backup, Action restore, AppContext appCtx)
{
_appCtx = appCtx;
_binExport = binExport;
_binExport.setEnabled(false);
_backup = backup;
_backup.setEnabled(false);
_restore = restore;
_restore.setEnabled(false);
_dirChooser = new JFileChooser();
......@@ -92,15 +110,17 @@ public class ModuleManager implements BaySelectionListener
JPanel pnl = new JPanel();
pnl.setBorder(BorderFactory.createEmptyBorder(4, 4, 4, 4));
pnl.setLayout(new BoxLayout(pnl, BoxLayout.PAGE_AXIS));
pnl.add(new JLabel("Export format"));
pnl.add(new JLabel("Export formats:"));
pnl.add(_extendedhex);
pnl.add(_plainhex);
pnl.add(_binary);
_dirChooser.setAccessory(pnl);
_dirChooser.setDialogTitle("Select directoy to export module contents to");
_dirChooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
_backupChooser = new JFileChooser();
_backupChooser.setFileFilter(new FileNameExtensionFilter("SaFariPark backup", "sfpb"));
}
......@@ -114,17 +134,23 @@ public class ModuleManager implements BaySelectionListener
_selectedMod = new Module(dev, bay);
_moduleName = dev.getModuleName(bay);
_binExport.setEnabled(true);
_backup.setEnabled(true);
_restore.setEnabled(true);
widthdrawChecksum();
checkChecksums();
} else {
_ctx = null;
_binExport.setEnabled(false);
_backup.setEnabled(false);
_restore.setEnabled(false);
_selectedMod = null;
widthdrawChecksum();
}
} catch (IOException e) {
_ctx = null;
_binExport.setEnabled(false);
_backup.setEnabled(false);
_restore.setEnabled(false);
widthdrawChecksum();
}
......@@ -180,6 +206,9 @@ public class ModuleManager implements BaySelectionListener
String filebasebase =String.format("sfp_%s_%s", _moduleName, _fileDateFormat.format(new Date()));
filebasebase = filebasebase.replace('/', '_');
filebasebase = filebasebase.replace('\\', '_');
List<String> filesWritten = new ArrayList<String>();
List<DataSource> orderedSources = new ArrayList<DataSource>();
......@@ -230,7 +259,7 @@ public class ModuleManager implements BaySelectionListener
} catch (Exception e) {};
}
} catch (IOException io) {
// TODO log!
}
} else {
......@@ -308,4 +337,186 @@ public class ModuleManager implements BaySelectionListener
return true;
}
public void backupBinary(Component parent)
{
_backupChooser.setDialogTitle("Create backup");
File file = null;
String filebasebase =String.format("%s_%s.sfpb", _fileDateFormat.format(new Date()), _moduleName);
filebasebase = filebasebase.replace('/', '_');
filebasebase = filebasebase.replace('\\', '_');
while (file == null)
{
file = new File(filebasebase);
_backupChooser.setSelectedFile(file);
if ((_backupChooser.showDialog(parent, "Backup") != JFileChooser.APPROVE_OPTION))
{
return;
}
file = _backupChooser.getSelectedFile();
if (file.exists()) {
if (JOptionPane.showConfirmDialog(parent, "Do you want to overwrite?","File already exists!", JOptionPane.YES_NO_OPTION) != JOptionPane.YES_OPTION) {
file = null;
}
}
}
try {
DataOutputStream dos = new DataOutputStream(new FileOutputStream(file));
try {
dos.writeBytes("sfpb"); // signature
dos.writeShort(0x100); // version
// for each source
for (DataSource ds : _ddmi.getSources())
{
if (!ds.isValid(_ctx)) continue;
byte[] data = ds.read(_ctx, ds.start, ds.size());
// write path name
dos.writeUTF(ds.getPath());
// length
dos.writeShort(data.length);
// and data
dos.write(data, 0, data.length);
}
dos.writeUTF("");
JOptionPane.showMessageDialog(parent, "File written:\n" + file, "Backup success!", JOptionPane.INFORMATION_MESSAGE);
} finally {
try {
dos.close();
} catch (Exception e) {};
}
} catch (IOException io) {
throw new RuntimeException("Failed to backup", io);
}
}
public void restoreBinary(Component parent) {
_backupChooser.setDialogTitle("Restore backup");
_backupChooser.setSelectedFile(null);
File file = null;
while (file == null)
{
if ((_backupChooser.showDialog(parent, "Restore") != JFileChooser.APPROVE_OPTION))
{
return;
}
file = _backupChooser.getSelectedFile();
if (!file.exists()) {
JOptionPane.showMessageDialog(parent, "File " + file + " doest not exist", "Error", JOptionPane.ERROR_MESSAGE);
file = null;
}
}
Map<String, byte[]> backup = new HashMap<String, byte[]>();
try {
DataInputStream dis = new DataInputStream(new FileInputStream(file));
try {
byte[] signature = new byte[4];
dis.readFully(signature);
if (! new String(signature).equals("sfpb")) throw new RuntimeException("Invalid backup");
if (dis.readShort() != 0x100) throw new RuntimeException("Backup version not supported");
String section = dis.readUTF();
while (!section.equals("") )
{
byte[] data = new byte[dis.readShort()];
dis.readFully(data);
backup.put(section, data);
// for legacy format
if (dis.available() == 0) break;
section = dis.readUTF();
}
} finally {
try {
dis.close();
} catch (Exception e) {};
}
} catch (IOException io) {
throw new RuntimeException("Failed to restore", io);
}
if (_appCtx.isLocked(_selectedMod)) {
_appCtx.showLockedMessage();
return;
}
StringBuilder sb = new StringBuilder();
for (DataSource ds : _ddmi.getSources())
{
if (!ds.isValid(_ctx)) continue;
if (!backup.containsKey(ds.getPath())) {
// log warning
sb.append("Section " + ds.getPath() + " not present in backup, kept as is\n");
continue;
}
byte[] data = backup.get(ds.getPath());
backup.remove(ds.getPath());
if (data.length != ds.size()) {
// log warning
sb.append("Section " + ds.getPath() + " has different size from backup, skipped\n");
continue;
}
try {
ds.write(_ctx, ds.start, data);
Thread.sleep(100);
} catch (Exception e)
{
sb.append("Aborted due to error: " + e + "\n");
break;
}
}
if (backup.size() > 0)
{
sb.append("Sections " + String.join(",", backup.keySet()) + " not restored");
}
if (sb.length() > 0) {
JOptionPane.showMessageDialog(parent, "Backup had warnings/errors:\n" + sb.toString() +
"\nYou need to reload the editor to see the new values", "Restore (partially) failed", JOptionPane.WARNING_MESSAGE);
} else {
JOptionPane.showMessageDialog(parent, "Backup from " + file + " restored" +
"\nYou need to reload the editor to see the new values", "Restore success!", JOptionPane.INFORMATION_MESSAGE);
}
}
}
......@@ -116,7 +116,7 @@ public class SaFariPark extends JFrame implements BaySelectionListener, WindowLi
}
};
private Action _saveBinary = new ExtendedAbstractAction("Save binary content", Resources.getIcon("document-export-4"), "Save a binary export") {
private Action _saveBinary = new ExtendedAbstractAction("Export binary data", Resources.getIcon("document-export-4"), "Save a binary export") {
@Override
public void actionPerformed(ActionEvent e)
......@@ -125,6 +125,25 @@ public class SaFariPark extends JFrame implements BaySelectionListener, WindowLi
}
};
private Action _backupBinary = new ExtendedAbstractAction("Backup module", Resources.getIcon("database-go"), "Make a backup module's content") {
@Override
public void actionPerformed(ActionEvent e)
{
_modMgr.backupBinary(SaFariPark.this);
}
};
private Action _restoreBinary = new ExtendedAbstractAction("Restore backup", Resources.getIcon("database-refresh"), "Restore a backup of module's content") {
@Override
public void actionPerformed(ActionEvent e)
{
_modMgr.restoreBinary(SaFariPark.this);
}
};
private Message _msg;
private Action _help = new ExtendedAbstractAction("Help", Resources.getIcon("help"), "Loads the manual") {
......@@ -180,7 +199,7 @@ public class SaFariPark extends JFrame implements BaySelectionListener, WindowLi
_logOut = new ActiveLogArea();
_monitor = new Monitor(appCtx);
_status = new StatusBar();
_modMgr = new ModuleManager(_saveBinary, appCtx);
_modMgr = new ModuleManager(_saveBinary, _backupBinary, _restoreBinary, appCtx);
_devMgr.addDeviceSelectedListener(_modMgr);
_appCtx.setMessagePane(_messagePane);
_appCtx.setSaFariPark(this);
......@@ -273,6 +292,9 @@ public class SaFariPark extends JFrame implements BaySelectionListener, WindowLi
tb.setFloatable(false);
tb.add(_selectOverlays);
tb.add(_saveBinary);
tb.addSeparator();
tb.add(_backupBinary);
tb.add(_restoreBinary);
tb.add(Box.createHorizontalGlue());
tb.add(_help);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment