
org.bidib.wizard.mvc.debug.controller.DebugInterfaceController Maven / Gradle / Ivy
package org.bidib.wizard.mvc.debug.controller;
import java.awt.Component;
import java.awt.Container;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.atomic.AtomicBoolean;
import javax.swing.JOptionPane;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils;
import org.bidib.jbidibc.core.ConnectionListener;
import org.bidib.jbidibc.core.exception.PortNotFoundException;
import org.bidib.jbidibc.core.exception.PortNotOpenedException;
import org.bidib.jbidibc.debug.DebugInterface;
import org.bidib.jbidibc.debug.DebugMessageListener;
import org.bidib.jbidibc.debug.DebugMessageReceiver;
import org.bidib.jbidibc.debug.DebugReader;
import org.bidib.wizard.locale.Resources;
import org.bidib.wizard.mvc.common.model.CommPort;
import org.bidib.wizard.mvc.common.view.DockKeys;
import org.bidib.wizard.mvc.debug.controller.listener.DebugInterfaceControllerListener;
import org.bidib.wizard.mvc.debug.model.DebugInterfaceModel;
import org.bidib.wizard.mvc.debug.view.DebugInterfaceView;
import org.bidib.wizard.mvc.debug.view.listener.DebugInterfaceViewListener;
import org.bidib.wizard.mvc.debug.view.listener.ProgressStatusCallback;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.vlsolutions.swing.docking.Dockable;
import com.vlsolutions.swing.docking.DockableState;
import com.vlsolutions.swing.docking.DockingConstants;
import com.vlsolutions.swing.docking.DockingDesktop;
import com.vlsolutions.swing.docking.DockingUtilities;
import com.vlsolutions.swing.docking.RelativeDockablePosition;
import com.vlsolutions.swing.docking.SingleDockableContainer;
import com.vlsolutions.swing.docking.TabbedDockableContainer;
public class DebugInterfaceController implements DebugInterfaceControllerListener {
private static final Logger LOGGER = LoggerFactory.getLogger(DebugInterfaceController.class);
private final DockingDesktop desktop;
private DebugInterfaceModel debugInterfaceModel;
private DebugInterfaceView debugInterfaceView;
private DebugInterface debugReader;
private DebugMessageReceiver messageReceiver;
private DebugMessageListener messageListener;
private List firmwareContent;
protected final ScheduledExecutorService sendFileWorker = Executors.newScheduledThreadPool(1);
public DebugInterfaceController(final DockingDesktop desktop) {
this.desktop = desktop;
}
public void start() {
// check if the debug interface view is already opened
String searchKey = DockKeys.DEBUG_INTERFACE_VIEW;
LOGGER.info("Search for view with key: {}", searchKey);
Dockable view = desktop.getContext().getDockableByKey(searchKey);
if (view != null) {
LOGGER.info("Select the existing debug interface view instead of open a new one.");
selectWindow(view);
return;
}
LOGGER.info("Create new DebugInterfaceView.");
debugInterfaceModel = new DebugInterfaceModel();
debugInterfaceView = new DebugInterfaceView(desktop, this, debugInterfaceModel);
DockableState[] dockables = desktop.getDockables();
LOGGER.info("Current dockables: {}", new Object[] { dockables });
if (dockables.length > 1) {
DockableState tabPanelNodeDetails = null;
// search the node details tab panel
for (DockableState dockable : dockables) {
if (DockKeys.DOCKKEY_TAB_PANEL.equals(dockable.getDockable().getDockKey())) {
LOGGER.info("Found the tab panel dockable.");
tabPanelNodeDetails = dockable;
break;
}
}
Dockable dock = desktop.getDockables()[1].getDockable();
if (tabPanelNodeDetails != null) {
LOGGER.info("Add the debug interface view next to the node details panel.");
dock = tabPanelNodeDetails.getDockable();
TabbedDockableContainer container = DockingUtilities.findTabbedDockableContainer(dock);
int order = 0;
if (container != null) {
order = container.getTabCount();
}
LOGGER.info("Add new debugInterfaceView at order: {}", order);
desktop.createTab(dock, debugInterfaceView, order, true);
}
else {
desktop.split(dock, debugInterfaceView, DockingConstants.SPLIT_RIGHT);
}
}
else {
desktop.addDockable(debugInterfaceView, RelativeDockablePosition.RIGHT);
}
debugInterfaceView.addDebugInterfaceViewListener(new DebugInterfaceViewListener() {
@Override
public void openConnection() {
Integer baudRate = debugInterfaceModel.getBaudRate();
if (baudRate == null) {
LOGGER.warn("No baudrate selected!");
JOptionPane.showMessageDialog(debugInterfaceView.getComponent(),
Resources.getString(DebugInterfaceController.class, "select-baudrate"), "Debug Interface",
JOptionPane.ERROR_MESSAGE);
return;
}
// PreferencesPortType debugPort = Preferences.getInstance().getPreviousSelectedDebugPort();
CommPort debugPort = debugInterfaceModel.getSelectedPort();
if (debugPort == null || StringUtils.isBlank(debugPort.getName())) {
LOGGER.warn("No debugPort selected!");
JOptionPane.showMessageDialog(debugInterfaceView.getComponent(),
Resources.getString(DebugInterfaceController.class, "select-port"), "Debug Interface",
JOptionPane.ERROR_MESSAGE);
return;
}
LOGGER.info("Current debugPort: {}", debugPort);
String portName = debugPort.getName();
if (debugReader == null) {
LOGGER.info("Create new instance of debug reader.");
try {
messageListener = new DebugMessageListener() {
@Override
public void debugMessage(final String message) {
LOGGER.info("debug message received: {}", message);
debugInterfaceView.addLog(message);
}
};
messageReceiver = new DebugMessageReceiver();
messageReceiver.addMessageListener(messageListener);
debugReader = new DebugReader(messageReceiver);
}
catch (Exception ex) {
LOGGER.warn("Open debug port failed.", ex);
}
}
try {
debugReader.open(portName, baudRate, new ConnectionListener() {
@Override
public void opened(String port) {
LOGGER.info("Port opened: {}", port);
debugInterfaceModel.setConnected(true);
}
@Override
public void closed(String port) {
LOGGER.info("Port closed: {}", port);
debugInterfaceModel.setConnected(false);
}
}, null);
}
catch (PortNotFoundException | PortNotOpenedException ex) {
LOGGER.warn("Open debug port failed.", ex);
JOptionPane.showMessageDialog(debugInterfaceView.getComponent(), "Open debug Port failed. Reason: "
+ ex.getReason(), "Debug Interface", JOptionPane.ERROR_MESSAGE);
}
catch (Exception ex) {
LOGGER.warn("Open debug port failed.", ex);
}
}
@Override
public void closeConnection() {
LOGGER.info("Close the debug connection.");
fireCloseConnection();
}
@Override
public void transmit() {
String sendText = debugInterfaceModel.getSendText();
LOGGER.info("Send text to debugReader: {}", sendText);
if (debugReader != null) {
debugReader.send(sendText);
}
}
@Override
public void transmitFile(final AtomicBoolean continueTransmit, final ProgressStatusCallback callback) {
fireTransmitFile(continueTransmit, callback);
}
});
}
private void fireTransmitFile(final AtomicBoolean continueTransmit, final ProgressStatusCallback callback) {
File sendFile = debugInterfaceModel.getSendFile();
LOGGER.info("Send file content to debugReader: {}", sendFile);
if (debugReader != null) {
// TODO prepare the data to send
this.firmwareContent = null;
InputStream input = null;
List firmwareContent = new ArrayList<>();
try {
byte[] buffer = new byte[200];
input = new FileInputStream(sendFile);
int readBytes = IOUtils.read(input, buffer);
while (readBytes > 0) {
LOGGER.debug("Number of bytes read: {}", readBytes);
byte[] packet = Arrays.copyOf(buffer, readBytes);
firmwareContent.add(packet);
readBytes = IOUtils.read(input, buffer);
}
// keep the firmware content
this.firmwareContent = firmwareContent;
}
catch (IOException ex) {
LOGGER.info("No firmware content file found.");
}
finally {
if (input != null) {
try {
input.close();
}
catch (Exception e) {
LOGGER.warn("Close input stream failed.", e);
}
input = null;
}
}
if (CollectionUtils.isNotEmpty(this.firmwareContent)) {
LOGGER.info("Send first packet to debug reader.");
debugInterfaceModel.setTransferInProgress(true);
sendFirmwarePackets(continueTransmit, callback);
}
}
}
private void sendFirmwarePackets(final AtomicBoolean continueTransmit, final ProgressStatusCallback callback) {
Runnable runnable = new Runnable() {
public void run() {
LOGGER.info("Start sending firmware packets.");
int packetsSent = 0;
int totalPackets = firmwareContent.size();
try {
for (byte[] content : firmwareContent) {
if (!continueTransmit.get()) {
LOGGER.warn("Transfer firmware was aborted by user.");
break;
}
debugReader.send(content);
packetsSent++;
if (callback != null) {
callback.statusChanged((packetsSent * 100) / totalPackets);
}
}
}
catch (Exception ex) {
LOGGER.warn("Send firmware content to debug reader failed.", ex);
}
debugInterfaceModel.setTransferInProgress(false);
if (callback != null) {
callback.transferFinished();
}
}
};
// Start the send firmware files process
sendFileWorker.execute(runnable);
}
private void selectWindow(Dockable dockable) {
// TODO this should also work with non-tabbed windows
TabbedDockableContainer container = DockingUtilities.findTabbedDockableContainer(dockable);
if (container != null) {
container.setSelectedDockable(dockable);
}
else {
LOGGER.warn("Container not available, select component directly.");
SingleDockableContainer singleContainer = DockingUtilities.findSingleDockableContainer(dockable);
if (singleContainer != null) {
try {
Component comp = (Component) singleContainer;
Container container2 = comp.getParent();
if (container2 != null) {
container2 = container2.getParent();
}
if (container2 != null) {
LOGGER.info("Request focus: {}", container2);
container2.requestFocus();
}
}
catch (Exception ex) {
LOGGER.warn("Request focus in single container failed.", ex);
}
}
else {
dockable.getComponent().requestFocusInWindow();
}
}
}
private void fireCloseConnection() {
if (debugReader != null) {
LOGGER.info("Close the debug reader.");
debugReader.close();
debugInterfaceModel.setConnected(false);
messageReceiver.removeMessageListener(messageListener);
messageListener = null;
messageReceiver = null;
debugReader = null;
}
else {
LOGGER.info("debug reader not available.");
}
}
@Override
public void viewClosed() {
LOGGER.info("The view is closed.");
fireCloseConnection();
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy