/* * BackupView.java * * Copyright (c) 2003-2004 Digi International * This program and the information contained in it is confidential and * proprietary to Digi International and may not be used, copied, or re- * produced without the prior written permission of Digi International. * */ package com.digi.config.ui; import com.digi.config.core.*; import com.digi.config.util.*; import javax.swing.*; import javax.swing.event.*; import javax.swing.tree.*; import javax.swing.border.*; import java.awt.*; import java.awt.event.*; import java.util.*; import java.io.*; import java.net.*; import javax.xml.parsers.*; import org.w3c.dom.*; /** * This class is a view panel that allow users to backup and restore * device settings for the ConnectMe device * * This view can be embedded in other panels as desired. */ public class BackupView extends ConfigViewImpl { /** A KvpNode that holds just the settings used in this view */ KvpNode viewSettingTree; /** listens to the device for changes to settings */ DeviceChangeListener settingChangeListener; /** Panel that holds the view content */ GridContentPanel content; GridContentPanel backupContent; GridContentPanel restoreContent; // Data Fields currently used in this view // UI Controls for each field JTextField restoreFileName_UIC; JButton backup_UIC; JButton browse_UIC; JButton restore_UIC; /** * Basic constructor. Sets up the tree view and the edit panel. */ public BackupView() throws Exception { // create the KvpNode and the kvpGroup change listener viewSettingTree = new KvpNode(); settingChangeListener = new DeviceChangeListener() { public void deviceChanged(DeviceChangeEvent e) { //SystemLog.debug("SerialBasicView was notified that device kvpGroup changed"); refreshViewKvpNode(); refreshViewControls(); } }; // Create the panel that will hold the view controls content = new GridContentPanel(this.getName(),2); // // Create the fields and put them on the view // // content.addHeadingBar("BackupRestoreHeading"); content.addBlankLine(); content.addTextLine("BackupRestoreDesc"); content.addBlankLine(); content.addTextLine("BackupDesc"); backupContent = new GridContentPanel(2); backup_UIC = backupContent.addAction(null, new ConfigAction("Backup1", this, "doBackupAction"), "Backup1Desc"); content.addSubPanel(backupContent); content.addBlankLine(); content.addTextLine("RestoreDesc"); restoreContent = new GridContentPanel(2); restoreFileName_UIC = restoreContent.addJTextField("RestoreLabel",null,300,null,0,false); browse_UIC = restoreContent.addAction(null, new ConfigAction("Browse", this, "doBrowseAction"), null,1,true); restore_UIC = restoreContent.addAction(null, new ConfigAction("Restore", this, "doRestoreAction"), null); content.addSubPanel(restoreContent); content.addVGlue(); } /** * Backup data to a device configuration data file */ public void doBackupAction() { SystemLog.debug("Backup!"); // prompt a file save dialog to get the name of the file to save device settings to JFileChooser chooser = new JFileChooser(); ExampleFileFilter filter = new ExampleFileFilter(); filter.addExtension("dcd"); filter.setDescription(ConfigResource.getUiRbString("BackupDlg.Description")); chooser.setFileFilter(filter); chooser.setDialogTitle(ConfigResource.getUiRbString("BackupDlg.Title")); chooser.setFileSelectionMode(JFileChooser.FILES_ONLY); chooser.setApproveButtonText(ConfigResource.getUiRbString("BackupDlg.Button")); chooser.setDialogType(JFileChooser.SAVE_DIALOG); int returnVal = chooser.showDialog(content, ConfigResource.getUiRbString("BackupDlg.Button")); if(returnVal == JFileChooser.APPROVE_OPTION) { try { String backupFileName = chooser.getSelectedFile().getCanonicalPath(); if (!backupFileName.endsWith(".dcd")) { backupFileName += ".dcd"; } // refresh to get latest device settings????? // open save file and stream settings into it File backupFile = new File(backupFileName); if (backupFile.exists()) { int reply = JOptionPane.showConfirmDialog(content,new JLabel("File '"+backupFileName+"' already exists. Are you sure you want to overwrite it?"),"Confirm overwrite", JOptionPane.YES_NO_OPTION); if (reply==JOptionPane.NO_OPTION) { SystemLog.log("Op1Cancelled", new Serializable[] {"Backup"}); return; } } backupFile.createNewFile(); FileOutputStream os = new FileOutputStream(backupFile); DataOutputStream dos = new DataOutputStream(os); StringBuffer outputBuffer = new StringBuffer(); outputBuffer.append("<"+RciProtocol.BACKUP_TAG+" version=\""+RciProtocol.PROTOCOL_VERSION_TAG+"\">\n"); // Grab a copy of the current device settings & remove the security information KvpNode backupSettings = device.getSettingTree(); KvpNode securitySettings = backupSettings.getChild("simple_password"); if (securitySettings!=null) { securitySettings.removeChild("password"); securitySettings.removeChild("public_comm"); securitySettings.removeChild("private_comm"); } backupSettings.toXml(outputBuffer,"",false); outputBuffer.append("\n"); dos.writeBytes(outputBuffer.toString()); // close file dos.close(); os.close(); SystemLog.log("Op1Succ", new Serializable[] {"Backup"}); } catch (Exception e) { SystemLog.log("Op1Fail", new Serializable[] {"Backup"}, e); } } } /** * Locate a device configuration data file */ public void doBrowseAction() { SystemLog.debug("Browse!"); JFileChooser chooser = new JFileChooser(); ExampleFileFilter filter = new ExampleFileFilter(); filter.addExtension("dcd"); filter.setDescription(ConfigResource.getUiRbString("RestoreDlg.Description")); chooser.setFileFilter(filter); chooser.setDialogTitle(ConfigResource.getUiRbString("RestoreDlg.Description")); chooser.setDialogType(JFileChooser.OPEN_DIALOG); chooser.setFileSelectionMode(JFileChooser.FILES_ONLY); int returnVal = chooser.showOpenDialog(content); if(returnVal == JFileChooser.APPROVE_OPTION) { try { restoreFileName_UIC.setText(chooser.getSelectedFile().getCanonicalPath()); } catch (Exception e) { SystemLog.log("Op1Fail", new Serializable[] {"Browse"}, e); } } } /** * Restore a device configuration data file */ public void doRestoreAction() { SystemLog.debug("Restore!"); String fileName = restoreFileName_UIC.getText(); File restoreFile = new File(fileName); // if the file is not found and the dcd extension was not provided then try adding it if (!restoreFile.exists() && !fileName.endsWith(".dcd")) { fileName += ".dcd"; restoreFile = new File(fileName); } Busy.begin(ConfigResource.getUiRbString("SaveChangesStatus")); // Restore the file if it exists if (restoreFile.exists()) { try { // open the restore file and parse contents FileInputStream is = new FileInputStream(restoreFile); DataInputStream dis = new DataInputStream(is); DocumentBuilderFactory domFactory = DocumentBuilderFactory.newInstance(); DocumentBuilder domBuilder = domFactory.newDocumentBuilder(); // use DOM parser to read the file Document resultDocument = domBuilder.parse(dis); Node commandNode = resultDocument.getFirstChild(); String command = commandNode.getNodeName(); if (!command.equals(RciProtocol.BACKUP_TAG)) { SystemLog.log("RestoreFileInvalidError", new Serializable[] {fileName}); return; } SystemLog.debug("Parsed rci_backup file. Extracting Settings"); // construct the cluster from the COM tree KvpNode restoreCluster = new KvpNode(commandNode); // Determine what level of RCI this backup file was create with String version = restoreCluster.getAttribute("version"); if (version==null) { version = "1.0"; } // Perform the restore - device handles processing old versions of backup data & refresh cached settings device.restoreBackupSettingTree(restoreCluster, version); SystemLog.log("Op1Succ",new Serializable[]{ConfigResource.getUiRbString("RestoreMenu")}); } catch (DeviceCommandException dce) { SystemLog.log("Op1Fail",new Serializable[]{ConfigResource.getUiRbString("RestoreMenu")},dce); } catch (DeviceValidationException dse) { // Find out what device fields are invalid SystemLog.debug("Invalid fields detected while saving to device", dse); KvpNode errorCluster = dse.getCluster(); Collection errors = errorCluster.getErrors(); StringBuffer msgBuff = new StringBuffer(); for (Iterator i=errors.iterator(); i.hasNext();) { RciCommandError error = (RciCommandError)i.next(); msgBuff.append(error.toString()+"\n"); } // popup a dialog showing the errors StringBuffer popupMsg = new StringBuffer(); popupMsg.append(ConfigResource.getUiRbString("ValidationErrorDesc")+"\n"); popupMsg.append(msgBuff); JOptionPane.showMessageDialog(this.content, popupMsg.toString(), ConfigResource.getUiRbString("ValidationErrorTitle"), JOptionPane.ERROR_MESSAGE); // Also add a log entry SystemLog.log("ValidationError", new Serializable[] {msgBuff.toString()}); } catch (Exception e) { SystemLog.log("Op1Fail",new Serializable[]{ConfigResource.getUiRbString("RestoreMenu")},e); } } else { SystemLog.log("RestoreFileInvalidError", new Serializable[] {fileName}); } Busy.end(); } /** * Returns a one word name identifying this view. */ public String getName() { return "BackupView"; } /** * Return the Component that displays the primary content for this view */ public Component getViewContent() { return content; } /** * Returns the Component that displays the buttons below the view. * If this view has no buttons to display this method returns null. */ public Component getViewButtons() { // We don't want buttons on this view so just return null return null; } /** * Informs view what device to work with. View should flush any * cached device data and mark current view content as invalid * so that it is refreshed appropriatly. */ public void setDevice(Device device) { super.setDevice(device); refreshViewKvpNode(); refreshViewControls(); device.addSettingChangeListener(settingChangeListener); } /** * Refreshes the local copy of the kvpGroup displayed in the view. The updated kvpGroup come * from those currently cached in the Device */ private void refreshViewKvpNode() { viewSettingTree.clear(); } /** * Refreshes the state of the controls in the view to match the data in the views kvpGroup. */ private void refreshViewControls() { } /** * This method is called to instruct the view that it is about to be made * active. When a view is active it needs to make sure its content is correct. * An example of why a panel may be inactive is if it were on a tabbed pane * and was not currently visible or if the user selected some other view. */ public void activate() { SystemLog.debug("Activating BackupView"); } /** * This method is called to instruct the view that it is about to be made * inactive. When a view is inactive, it does not need to worry * about maintaining its content in a correct state. An example of why a panel * may be inactive is if it were on a tabbed pane and was not currently visible * or if the user selected some other view. */ public void deactivate() { SystemLog.debug("Deactivating BackupView"); } /** * Indicates if any changes have been made by the user that have not yet been * saved to the device(ie committed). */ public boolean isChanged() { return false; } /** * This method instructs the view to place any changes the user has made within * the view into the provided clusters. Once the changes have been saved to * to the device, a subsequent call to commitChanges() will be made. */ public void getChanges(KvpNode settingCluster, KvpNode stateCluster) { } /** * Instructs the view to consider any user changes within the view as * saved to the device (ie committed). */ public void commitChanges() { } /** * Instructs the view to discard any changes the user has made within the * view and revert those fields to the original state. The view is also * free to refresh all its fields to the present cached state of the device at * this time. */ public void cancelChanges() { } }