use of CCDD.CcddClassesDataTable.CCDDException in project CCDD by nasa.
the class CcddReservedMsgIDEditorDialog method createReservedMsgIDTable.
/**
********************************************************************************************
* Create the reserved message ID table
*
* @return Reference to the scroll pane in which the table is placed
********************************************************************************************
*/
private JScrollPane createReservedMsgIDTable() {
// Define the reserved message ID editor JTable
msgIDTable = new CcddJTableHandler() {
/**
************************************************************************************
* Allow multiple line display in all columns
************************************************************************************
*/
@Override
protected boolean isColumnMultiLine(int column) {
return true;
}
/**
************************************************************************************
* Hide the the specified columns
************************************************************************************
*/
@Override
protected boolean isColumnHidden(int column) {
return column == ReservedMsgIDEditorColumnInfo.OID.ordinal();
}
/**
************************************************************************************
* Override isCellEditable so that all columns can be edited
************************************************************************************
*/
@Override
public boolean isCellEditable(int row, int column) {
return true;
}
/**
************************************************************************************
* Allow pasting data into the reserved message ID cells
************************************************************************************
*/
@Override
protected boolean isDataAlterable(Object[] rowData, int row, int column) {
return isCellEditable(convertRowIndexToView(row), convertColumnIndexToView(column));
}
/**
************************************************************************************
* Validate changes to the editable cells
*
* @param tableData
* list containing the table data row arrays
*
* @param row
* table model row number
*
* @param column
* table model column number
*
* @param oldValue
* original cell contents
*
* @param newValue
* new cell contents
*
* @param showMessage
* true to display the invalid input dialog, if applicable
*
* @param isMultiple
* true if this is one of multiple cells to be entered and checked; false if
* only a single input is being entered
*
* @return Always returns false
***********************************************************************************
*/
@Override
protected Boolean validateCellContent(List<Object[]> tableData, int row, int column, Object oldValue, Object newValue, Boolean showMessage, boolean isMultiple) {
// Reset the flag that indicates the last edited cell's content is invalid
setLastCellValid(true);
// Create a string version of the new value
String newValueS = newValue.toString();
try {
// Check if the value isn't blank
if (!newValueS.isEmpty()) {
// Check if the message ID has been changed and if the ID isn't blank
if (column == ReservedMsgIDEditorColumnInfo.MSG_ID.ordinal()) {
// type
if (!newValueS.matches(InputDataType.HEXADECIMAL_RANGE.getInputMatch())) {
throw new CCDDException("Invalid message ID; " + InputDataType.HEXADECIMAL_RANGE.getInputName().toLowerCase() + " expected");
}
// Convert the lower and upper (if present) values into integers
int[] lowHigh = rsvMsgIDHandler.parseReservedMsgIDs(newValueS);
// upper value
if (lowHigh[1] != -1 && lowHigh[0] > lowHigh[1]) {
// inform the user that the values are invalid
throw new CCDDException("Invalid message ID range; lower value must be <= upper value");
}
// creating a duplicate
for (int otherRow = 0; otherRow < getModel().getRowCount(); otherRow++) {
// Check if this row isn't the one being edited
if (otherRow != row) {
// Get the message ID from this row
String otherValue = tableData.get(otherRow)[column].toString();
// falls within the range of this row's ID(s)
if (!otherValue.isEmpty() && rsvMsgIDHandler.isWithinRange(lowHigh, otherValue)) {
// the range of an existing reserved message ID
throw new CCDDException("Message ID(s) already reserved");
}
}
}
// Clean up the lower ID text
String[] range = newValueS.split("\\s*+-\\s*+");
newValueS = InputDataType.HEXADECIMAL.formatInput(range[0]);
// Check if the ID is a range
if (range.length == 2) {
// Clean up the upper ID text
newValueS += " - " + InputDataType.HEXADECIMAL.formatInput(range[1]);
}
// Store the new value in the table data array after formatting the
// cell value
newValue = newValueS;
tableData.get(row)[column] = newValueS;
}
}
} catch (CCDDException ce) {
// Set the flag that indicates the last edited cell's content is invalid
setLastCellValid(false);
// Check if the input error dialog should be displayed
if (showMessage) {
// Inform the user that the input value is invalid
new CcddDialogHandler().showMessageDialog(CcddReservedMsgIDEditorDialog.this, "<html><b>" + ce.getMessage(), "Invalid Input", JOptionPane.WARNING_MESSAGE, DialogOption.OK_OPTION);
}
// Restore the cell contents to its original value and pop the edit from the
// stack
tableData.get(row)[column] = oldValue;
msgIDTable.getUndoManager().undoRemoveEdit();
}
return false;
}
/**
************************************************************************************
* Load the table reserved message ID definition values into the table and format the
* table cells
************************************************************************************
*/
@Override
protected void loadAndFormatData() {
// Place the data into the table model along with the column names, set up the
// editors and renderers for the table cells, set up the table grid lines, and
// calculate the minimum width required to display the table information
setUpdatableCharacteristics(committedData, ReservedMsgIDEditorColumnInfo.getColumnNames(), null, ReservedMsgIDEditorColumnInfo.getToolTips(), true, true, true);
}
/**
************************************************************************************
* Override prepareRenderer to allow adjusting the background colors of table cells
************************************************************************************
*/
@Override
public Component prepareRenderer(TableCellRenderer renderer, int row, int column) {
JComponent comp = (JComponent) super.prepareRenderer(renderer, row, column);
// invalid highlighting, if applicable)
if (!(isFocusOwner() && isRowSelected(row) && (isColumnSelected(column) || !getColumnSelectionAllowed()))) {
boolean found = true;
// Check if the cell is required and is empty
if (ReservedMsgIDEditorColumnInfo.values()[msgIDTable.convertColumnIndexToModel(column)].isRequired() && msgIDTable.getValueAt(row, column).toString().isEmpty()) {
// Set the flag indicating that the cell value is invalid
found = false;
}
// Check if the cell value is invalid
if (!found) {
// Change the cell's background color
comp.setBackground(ModifiableColorInfo.REQUIRED_BACK.getColor());
}
}
return comp;
}
/**
************************************************************************************
* Override the CcddJTableHandler method to produce an array containing empty values
* for a new row in this table
*
* @return Array containing blank cell values for a new row
************************************************************************************
*/
@Override
protected Object[] getEmptyRow() {
return ReservedMsgIDEditorColumnInfo.getEmptyRow();
}
/**
************************************************************************************
* Handle a change to the table's content
************************************************************************************
*/
@Override
protected void processTableContentChange() {
// Add or remove the change indicator based on whether or not any unstored changes
// exist
setTitle(DIALOG_TITLE + (msgIDTable.isTableChanged(committedData) ? "*" : ""));
// Force the table to redraw so that changes to the cells are displayed
repaint();
}
};
// Place the table into a scroll pane
JScrollPane scrollPane = new JScrollPane(msgIDTable);
// Disable storage of edit operations during table creation
msgIDTable.getUndoHandler().setAllowUndo(false);
// Set common table parameters and characteristics
msgIDTable.setFixedCharacteristics(scrollPane, true, ListSelectionModel.MULTIPLE_INTERVAL_SELECTION, TableSelectionMode.SELECT_BY_CELL, false, ModifiableColorInfo.TABLE_BACK.getColor(), true, true, ModifiableFontInfo.DATA_TABLE_CELL.getFont(), true);
// Re-enable storage of edit operations
msgIDTable.getUndoHandler().setAllowUndo(true);
return scrollPane;
}
use of CCDD.CcddClassesDataTable.CCDDException in project CCDD by nasa.
the class CcddSchedulerEditorHandler method initialize.
/**
********************************************************************************************
* Create a telemetry table
********************************************************************************************
*/
@SuppressWarnings("serial")
private void initialize() {
// Create a border for the table and list panes, and an empty border
Border border = BorderFactory.createCompoundBorder(BorderFactory.createBevelBorder(BevelBorder.LOWERED, Color.LIGHT_GRAY, Color.GRAY), BorderFactory.createEmptyBorder(ModifiableSpacingInfo.INPUT_FIELD_PADDING.getSpacing(), ModifiableSpacingInfo.INPUT_FIELD_PADDING.getSpacing(), ModifiableSpacingInfo.INPUT_FIELD_PADDING.getSpacing(), ModifiableSpacingInfo.INPUT_FIELD_PADDING.getSpacing()));
Border emptyBorder = BorderFactory.createEmptyBorder();
// Initialize the layout constraints
GridBagConstraints gbc = new GridBagConstraints(0, 0, 1, 1, 1.0, 0.0, GridBagConstraints.LINE_START, GridBagConstraints.BOTH, new Insets(0, 0, 0, 0), 0, 0);
// Initialize the telemetry scheduler
initializeSchedulerTable();
// Initialize the scheduler table object
schedulerTable = new CcddJTableHandler(5) {
/**
************************************************************************************
* Allow multiple line display in the specified column only
************************************************************************************
*/
@Override
protected boolean isColumnMultiLine(int column) {
return column == SchedulerColumn.NAME.ordinal();
}
/**
************************************************************************************
* Allow resizing of the specified column only
************************************************************************************
*/
@Override
protected boolean isColumnResizable(int column) {
return column == SchedulerColumn.NAME.ordinal();
}
/**
************************************************************************************
* Allow editing of the table cells in the specified columns only
************************************************************************************
*/
@Override
public boolean isCellEditable(int row, int column) {
return column == SchedulerColumn.NAME.ordinal() || (column == SchedulerColumn.ID.ordinal() && messages.get(row).getNumberOfSubMessages() <= 1) || (column > SchedulerColumn.ID.ordinal() && messages.get(row).getNumberOfSubMessages() > 1 && column <= SchedulerColumn.ID.ordinal() + messages.get(row).getNumberOfSubMessages());
}
/**
************************************************************************************
* Validate changes to the data field value cells; e.g., verify cell content and, if
* found invalid, revert to the original value
*
* @param tableData
* list containing the table data row arrays
*
* @param row
* table model row number
*
* @param column
* table model column number
*
* @param oldValue
* original cell contents
*
* @param newValue
* new cell contents
*
* @param showMessage
* unused
*
* @param isMultiple
* unused
*
* @return Value of ShowMessage
***********************************************************************************
*/
@Override
protected Boolean validateCellContent(List<Object[]> tableData, int row, int column, Object oldValue, Object newValue, Boolean showMessage, boolean isMultiple) {
// Reset the flag that indicates the last edited cell's content is invalid
setLastCellValid(true);
// Create a string version of the new value
String newValueS = newValue.toString();
try {
// Check if this is the name column
if (column == SchedulerColumn.NAME.ordinal()) {
// Check if the value name is blank
if (newValueS.isEmpty()) {
// Inform the user that the message name cannot be blank
throw new CCDDException("Message name must be entered");
}
// Check if the message name is an alphanumeric
if (!newValueS.matches(InputDataType.ALPHANUMERIC.getInputMatch())) {
// Inform the user that the message name contains invalid characters
throw new CCDDException("Invalid characters in message name");
}
// Step through each message
for (Message message : messages) {
// Check if the new name matches an existing one
if (messages.indexOf(message) != row && message.getName().equals(newValueS)) {
// Inform the user that the message name already is in use
throw new CCDDException("Message name is already in use");
}
}
// Store the new message name
messages.get(row).setName(newValueS);
// Update the assigned variables tab and options list with the new name
tabbedPane.setTitleAt(tabbedPane.getSelectedIndex(), newValueS);
schedulerHndlr.getTelemetryOptions();
// Change references to the original message name to the new name in the
// assignment tree so that the tree builds correctly
assignmentTree.updateMessageName(oldValue.toString(), newValueS);
} else // Check if this is an ID column
if (column >= SchedulerColumn.ID.ordinal()) {
// Check if the message ID is a hexadecimal
if (!newValueS.matches(InputDataType.HEXADECIMAL.getInputMatch())) {
// Inform the user that the message name contains invalid characters
throw new CCDDException("Invalid characters in message ID");
}
// Format the hexadecimal value
newValueS = InputDataType.HEXADECIMAL.formatInput(newValueS);
// Check that the new value isn't a blank
if (!newValueS.isEmpty()) {
// Convert the ID to an integer
int id = Integer.decode(newValueS);
// Step through each row in the table
for (int checkRow = 0; checkRow < tableData.size(); checkRow++) {
// Step through each column containing an ID
for (int checkCol = SchedulerColumn.ID.ordinal(); checkCol < tableData.get(checkRow).length; checkCol++) {
// updated, and that the new ID matches that in another ID cell
if (!(row == checkRow && column == checkCol) && !tableData.get(checkRow)[checkCol].toString().isEmpty() && id == Integer.decode(tableData.get(checkRow)[checkCol].toString())) {
// Inform the user that the message name already is in use
throw new CCDDException("Message ID is already in use");
}
}
}
}
// Update the table with the formatted value
tableData.get(row)[column] = newValueS;
// Check if this is the parent message's ID
if (column == SchedulerColumn.ID.ordinal()) {
// Store the new message ID
messages.get(row).setID(newValueS);
} else // This is a sub-message ID
{
// Store the new sub-message ID
messages.get(row).getSubMessage(column - SchedulerColumn.ID.ordinal() - 1).setID(newValueS);
}
}
} catch (CCDDException ce) {
// Set the flag that indicates the last edited cell's content is invalid
setLastCellValid(false);
// Inform the user that the input value is invalid
new CcddDialogHandler().showMessageDialog(schedulerHndlr.getSchedulerDialog().getDialog(), "<html><b>" + ce.getMessage(), "Invalid Input", JOptionPane.WARNING_MESSAGE, DialogOption.OK_OPTION);
// Restore the cell contents to its original value
tableData.get(row)[column] = oldValue;
getUndoManager().undoRemoveEdit();
}
return showMessage;
}
/**
************************************************************************************
* Load the table data field definition values into the table and format the table
* cells
************************************************************************************
*/
@Override
protected void loadAndFormatData() {
// Place the data into the table model along with the column names, set up the
// editors and renderers for the table cells, set up the table grid lines, and
// calculate the minimum width required to display the table information
setUpdatableCharacteristics(currentData, getColumnNames(), null, null, true, true, true);
}
/**
************************************************************************************
* Override prepareRenderer to allow adjusting the background colors of table cells
************************************************************************************
*/
@Override
public Component prepareRenderer(TableCellRenderer renderer, int row, int column) {
JComponent comp = (JComponent) super.prepareRenderer(renderer, row, column);
// color
if (comp.getBackground() != ModifiableColorInfo.FOCUS_BACK.getColor() && comp.getBackground() != ModifiableColorInfo.SELECTED_BACK.getColor() && !isCellEditable(row, column)) {
// Shade the cell's foreground and background colors
comp.setForeground(getValueAt(row, column).toString().startsWith("-") ? ModifiableColorInfo.INVALID_TEXT.getColor() : ModifiableColorInfo.PROTECTED_TEXT.getColor());
comp.setBackground(ModifiableColorInfo.PROTECTED_BACK.getColor());
}
return comp;
}
/**
************************************************************************************
* Override the CcddJTableHandler method to handle sorting the Size column
************************************************************************************
*/
@Override
protected void setTableSortable() {
// Remove the current sorter, if present. The number of columns may have changed
// (due to adding/removing sub-messages) so the sorter must be rebuilt
setRowSorter(null);
super.setTableSortable();
// Create a runnable object to be executed
SwingUtilities.invokeLater(new Runnable() {
/**
****************************************************************************
* Execute after all pending Swing events are finished. This allows the number
* of viewable columns to catch up with the column model when a column is added
* or removed
****************************************************************************
*/
@Override
public void run() {
// Get the table's row sorter
TableRowSorter<?> sorter = (TableRowSorter<?>) getRowSorter();
// Check if the table has a sorter (i.e., has at least one row)
if (sorter != null) {
// the telemetry scheduler)
for (int column = SchedulerColumn.ID.ordinal(); column < getModel().getColumnCount(); column++) {
// Add a hexadecimal sort comparator
sorter.setComparator(column, new Comparator<String>() {
/**
************************************************************
* Override the comparison when sorting columns with a
* hexadecimal input type format
************************************************************
*/
@Override
public int compare(String cell1, String cell2) {
int result;
// Check if either cell is empty
if (cell1.isEmpty() || cell2.isEmpty()) {
// Compare as text (alphabetically)
result = cell1.compareTo(cell2);
} else // Neither cell is empty
{
// Get the hexadecimal cell values and convert them to
// base 10 integers for comparison
result = Integer.compare(Integer.decode(cell1), Integer.decode(cell2));
}
return result;
}
});
}
}
}
});
}
};
// Create a listener for scheduler table row and column selection changes
ListSelectionListener rowColListener = new ListSelectionListener() {
/**
************************************************************************************
* Handle a scheduler table row or column selection change
************************************************************************************
*/
@Override
public void valueChanged(ListSelectionEvent lse) {
// Check if this is the last of the series of changes
if (!lse.getValueIsAdjusting() && (schedulerTable.getSelectedRow() != previousRow || schedulerTable.getSelectedColumn() != previousColumn)) {
// Update the tabbed pane for the selected message
updateAssignedVariablesTabs();
// Update the assignment tree/list
updateAssignmentList();
// Store the selected row and column indices for comparison when another cell
// is selected
previousRow = schedulerTable.getSelectedRow();
previousColumn = schedulerTable.getSelectedColumn();
}
}
};
// Add a listener for changes to the table's row selection
schedulerTable.getSelectionModel().addListSelectionListener(rowColListener);
// Add a listener for changes to the table's column selection
schedulerTable.getColumnModel().getSelectionModel().addListSelectionListener(rowColListener);
// Place the table into a scroll pane
JScrollPane schedulerScrollPane = new JScrollPane(schedulerTable);
schedulerScrollPane.setBorder(border);
// Set common table parameters and characteristics
schedulerTable.setFixedCharacteristics(schedulerScrollPane, false, ListSelectionModel.SINGLE_SELECTION, TableSelectionMode.SELECT_BY_CELL, false, ModifiableColorInfo.TABLE_BACK.getColor(), true, true, ModifiableFontInfo.DATA_TABLE_CELL.getFont(), true);
// Get the table model and undo manager to shorten later calls
schTableModel = (UndoableTableModel) schedulerTable.getModel();
// Create a scroll pane to contain the assignment tree/list
JScrollPane assignScrollPane = null;
// Check if this is the telemetry scheduler
if (schedulerHndlr.getSchedulerOption() == TELEMETRY_SCHEDULER) {
// Get a reference to the telemetry scheduler input to shorten subsequent calls
CcddTelemetrySchedulerInput tlmInput = (CcddTelemetrySchedulerInput) schedulerHndlr.getSchedulerInput();
// Create an assignment tree specifying a null rate & message so the tree is initially
// empty
assignmentTree = new CcddAssignmentTreeHandler(ccddMain, null, tlmInput.getLinkTree().getLinkHandler(), tlmInput.getVariableTree().getTableTreePathList(null, tlmInput.getVariableTree().getNodeByNodeName(UNLINKED_VARIABLES_NODE_NAME), -1), ccddMain.getMainFrame());
} else // Check if this is the application scheduler
if (schedulerHndlr.getSchedulerOption() == APPLICATION_SCHEDULER) {
// Initialize the assignment list and add it to a scroll pane that will be placed next
// to the variable list
assignmentList = new JList<String>();
assignmentList.setModel(new DefaultListModel<String>());
assignmentList.setFont(ModifiableFontInfo.LABEL_PLAIN.getFont());
assignScrollPane = new JScrollPane(assignmentList);
assignScrollPane.setBorder(border);
// Set the size of the assignment scroll pane
assignScrollPane.setPreferredSize(new Dimension(Math.min(Math.max(assignScrollPane.getPreferredSize().width, 150), 250), assignScrollPane.getPreferredSize().height));
assignScrollPane.setMinimumSize(assignScrollPane.getPreferredSize());
}
// Create panels to hold the components tablePnl = new JPanel(new GridBagLayout());
JPanel schedulerPnl = new JPanel(new GridBagLayout());
JPanel assignmentPnl = new JPanel(new GridBagLayout());
schedulerPnl.setBorder(emptyBorder);
assignmentPnl.setBorder(emptyBorder);
// Set the scheduler panel size so that the panel can't be resized in width less than that
// needed to display the default columns
int[] colWidths = schedulerTable.getColumnWidths();
int prefWidth = 8 + colWidths[0] + colWidths[1] + (schedulerHndlr.getSchedulerOption() == TELEMETRY_SCHEDULER ? colWidths[2] : 0);
schedulerScrollPane.setPreferredSize(new Dimension(prefWidth, schedulerScrollPane.getPreferredSize().height));
schedulerPnl.setMinimumSize(schedulerScrollPane.getPreferredSize());
// Create the scheduler table label
JLabel schedulerLbl = new JLabel("Scheduler");
schedulerLbl.setFont(ModifiableFontInfo.LABEL_BOLD.getFont());
schedulerLbl.setForeground(ModifiableColorInfo.SPECIAL_LABEL_TEXT.getColor());
// Add the scheduler label and scroll pane to the panel
schedulerPnl.add(schedulerLbl, gbc);
gbc.weighty = 1.0;
gbc.insets.top = ModifiableSpacingInfo.LABEL_VERTICAL_SPACING.getSpacing() / 2;
gbc.insets.bottom = ModifiableSpacingInfo.LABEL_VERTICAL_SPACING.getSpacing() / 2;
gbc.gridy++;
schedulerPnl.add(schedulerScrollPane, gbc);
// Create the assignment list label and add it to the panel
JLabel assignmentLbl = new JLabel("");
assignmentLbl.setFont(ModifiableFontInfo.LABEL_BOLD.getFont());
assignmentLbl.setForeground(ModifiableColorInfo.SPECIAL_LABEL_TEXT.getColor());
gbc.insets.top = 0;
gbc.weighty = 0.0;
gbc.gridx = 0;
gbc.gridy = 0;
assignmentPnl.add(assignmentLbl, gbc);
gbc.weighty = 1.0;
gbc.gridy = 1;
// Check if this is the telemetry scheduler
if (schedulerHndlr.getSchedulerOption() == TELEMETRY_SCHEDULER) {
// Adjust the tab area's insets so that the scheduler and tabs are aligned. Note that
// the Nimbus L&F has hard-coded insets, so can't be changed;
UIManager.getDefaults().put("TabbedPane.tabAreaInsets", new Insets(0, 0, 0, 0));
UIManager.getDefaults().put("TabbedPane.tabsOverlapBorder", true);
// Create a tabbed pane to contain the variable tree for the message and any
// sub-messages
tabbedPane = new JTabbedPane(JTabbedPane.TOP);
tabbedPane.setFont(ModifiableFontInfo.LABEL_BOLD.getFont());
// Listen for tab selection changes
tabbedPane.addChangeListener(new ChangeListener() {
/**
********************************************************************************
* Handle tab selection change
********************************************************************************
*/
@Override
public void stateChanged(ChangeEvent ce) {
// update the assignment tree
if (!isTabUpdate) {
// Get the currently selected tab index
int tabIndex = tabbedPane.getSelectedIndex();
// Check if a tab is selected
if (tabIndex != -1) {
// Get the currently selected message in the scheduler table
Message message = getSelectedMessage();
// Check if a message is selected
if (message != null) {
// Select the row and column in the scheduler table corresponding
// to the selected message tab
schedulerTable.changeSelection(schedulerTable.getSelectedRow(), SchedulerColumn.ID.ordinal() + tabIndex, false, false);
}
}
// Update the assignment tree/list
updateAssignmentList();
}
}
});
// Set the assignment tree title
assignmentLbl.setText("Assigned Variables");
// Create the assignment tree and place it within the tabbed pane
tabbedPane.insertTab("<html><i>No message selected", null, assignmentTree.createTreePanel(TreeSelectionModel.DISCONTIGUOUS_TREE_SELECTION), null, 0);
// Add the tabbed pane to the panel
assignmentPnl.add(tabbedPane, gbc);
} else // Check if this is the application scheduler
if (schedulerHndlr.getSchedulerOption() == APPLICATION_SCHEDULER) {
// Set the assignment list title
assignmentLbl.setText("Assigned Applications");
// Add the assignment list to the panel
gbc.insets.top = 0;
assignmentPnl.add(assignScrollPane, gbc);
// Set the tabbed pane to null so that the application scheduler ignores it
tabbedPane = null;
}
// Add the scheduler table and assignment tree/list to the split pane
tableSpltPn = new CustomSplitPane(schedulerPnl, assignmentPnl, null, JSplitPane.HORIZONTAL_SPLIT);
}
use of CCDD.CcddClassesDataTable.CCDDException in project CCDD by nasa.
the class CcddDbControlHandler method connectToDatabase.
/**
********************************************************************************************
* Connect to a database
*
* @param databaseName
* name of the database to open
*
* @return true if the connection attempt failed
********************************************************************************************
*/
private boolean connectToDatabase(String databaseName) {
boolean errorFlag = false;
try {
connectionStatus = NO_CONNECTION;
// Connect the user to the database
connection = DriverManager.getConnection(getDatabaseURL(databaseName), activeUser, activePassword);
dbCommand.setStatement(connection.createStatement());
// Reset the flag that indicates a connection failure occurred due to a missing
// password
isMissingPassword = false;
// Set the transaction isolation mode to serializable to prevent transaction collisions
// if there are concurrent users of the database
connection.setTransactionIsolation(Connection.TRANSACTION_SERIALIZABLE);
// Disable automatic commit of database updates. This allows database commands to be
// grouped prior to committing
connection.setAutoCommit(false);
// Store the database connection
dbCommand.setConnection(connection);
// Save the name of the newly connected database
setDatabaseName(databaseName);
// Check if the default database is selected
if (databaseName.equals(DEFAULT_DATABASE)) {
// Set the connection status to indicate the default database is connected
connectionStatus = TO_SERVER_ONLY;
// Inform the user that the server connection succeeded
eventLog.logEvent(SUCCESS_MSG, "Connected to server as user '" + activeUser + "'");
} else // A database other than the default is selected
{
// The connection to the server must exist in order to reach this point, so set the
// connection status to indicate the server is connected. Once the project
// connection is completed the flag is updated accordingly
connectionStatus = TO_SERVER_ONLY;
// lock status is ignored
if (!ccddMain.isGUIHidden()) {
// Get the database lock status
Boolean isLocked = getDatabaseLockStatus(databaseName);
// Check if an error occurred obtaining the lock status
if (isLocked == null) {
// Set the error flag
throw new CCDDException("");
}
// Check if the database is locked
if (isLocked) {
throw new SQLException("database is locked");
}
}
boolean isAllowed = false;
// Step through each database
for (String database : queryDatabaseByUserList(ccddMain.getMainFrame(), activeUser)) {
// access to this database
if (databaseName.equalsIgnoreCase(database.split(DATABASE_COMMENT_SEPARATOR, 2)[0])) {
// Set the flag indicating the user has access and stop searching
isAllowed = true;
break;
}
}
// Check if the user has access to this database
if (!isAllowed) {
// Set the error flag
throw new CCDDException("");
}
// Get the database owner
activeOwner = queryDatabaseOwner(databaseName, ccddMain.getMainFrame())[0];
// Set the connection status to indicate a database is connected
connectionStatus = TO_DATABASE;
// Check if an automatic backup was scheduled via the command line argument
if (!backupFileName.isEmpty()) {
// Check if the backup file name is missing the correct extension
if (!backupFileName.endsWith(FileExtension.DBU.getExtension())) {
// Append the backup file extension to the file name
backupFileName += FileExtension.DBU.getExtension();
}
// Backup the database
backupDatabaseInBackground(databaseName, new FileEnvVar(backupFileName));
// Reset the backup file name to prevent another automatic backup
backupFileName = "";
}
// Inform the user that the database connection succeeded
eventLog.logEvent(SUCCESS_MSG, "Connected to project '" + activeProject + "' as user '" + activeUser + "'");
}
} catch (SQLException se) {
// Check if the connection failed due to a missing or invalid password
if ((se.getMessage().contains("authentication failed") || se.getMessage().contains("password")) && !ccddMain.isGUIHidden()) {
// Set the flag that indicates a connection failure occurred due to a missing
// password
isMissingPassword = true;
} else // Connection failed for reason other than a missing password
{
// Inform the user that the database connection failed
eventLog.logFailEvent(ccddMain.getMainFrame(), "Cannot connect to " + (activeDatabase.equals(DEFAULT_DATABASE) ? "server" : "project database '" + getServerAndDatabase(databaseName) + "'") + " as user '" + activeUser + "'; cause '" + se.getMessage() + "'", "<html><b>Cannot connect to " + (activeDatabase.equals(DEFAULT_DATABASE) ? "server" : "project '</b>" + databaseName + "<b>'"));
}
errorFlag = true;
} catch (CCDDException ce) {
errorFlag = true;
}
// Check if a connection is established
if (!errorFlag) {
// Log the PostgreSQL and JDBC versions
eventLog.logEvent(EventLogMessageType.STATUS_MSG, "PostgreSQL: " + getDatabaseVersion() + " *** JDBC: " + getJDBCVersion());
}
return errorFlag;
}
use of CCDD.CcddClassesDataTable.CCDDException in project CCDD by nasa.
the class CcddFileIOHandler method createTablesFromDefinitions.
/**
********************************************************************************************
* Create one or more data tables from the supplied table definitions
*
* @param tableDefinitions
* list of table definitions for the table(s) to create
*
* @param replaceExisting
* true to replace a table that already exists in the database
*
* @param parent
* GUI component calling this method
*
* @throws CCDDException
* If the table path name is invalid or the table cannot be created from the table
* definition
********************************************************************************************
*/
private void createTablesFromDefinitions(List<TableDefinition> tableDefinitions, boolean replaceExisting, final Component parent) throws CCDDException {
cancelImport = false;
boolean prototypesOnly = true;
List<String> skippedTables = new ArrayList<String>();
// Get the list of all tables, including the paths for child structure tables
CcddTableTreeHandler tableTree = new CcddTableTreeHandler(ccddMain, TableTreeType.TABLES, parent);
List<String> allTables = tableTree.getTableTreePathList(null);
// tables
for (int loop = 1; loop <= 2 && !cancelImport; loop++) {
// Step through each table definition
for (TableDefinition tableDefn : tableDefinitions) {
// Check if the table path/name format is valid
if (!tableDefn.getName().matches(InputDataType.VARIABLE.getInputMatch() + "(?:$|(?:," + InputDataType.VARIABLE.getInputMatch() + "\\." + InputDataType.VARIABLE.getInputMatch() + ")+)")) {
// Inform the user the table path/name isn't in the correct format
throw new CCDDException("Invalid table path/name '</b>" + tableDefn.getName() + "<b>' format");
}
// Check if the table import was canceled by the user
if (cancelImport) {
// Add the table to the list of those skipped
skippedTables.add(tableDefn.getName());
continue;
}
// or if this is a child table and this is the second pass
if (!tableDefn.getData().isEmpty() && (!tableDefn.getName().contains(",") != !prototypesOnly)) {
// Get the table type definition for this table
TypeDefinition typeDefn = tableTypeHandler.getTypeDefinition(tableDefn.getTypeName());
// Get the number of table columns
int numColumns = typeDefn.getColumnCountVisible();
// Create the table information for the new table
TableInformation tableInfo = new TableInformation(tableDefn.getTypeName(), tableDefn.getName(), new String[0][0], tableTypeHandler.getDefaultColumnOrder(tableDefn.getTypeName()), tableDefn.getDescription(), !tableDefn.getName().contains("."), tableDefn.getDataFields().toArray(new String[0][0]));
// Check if the new table is not a prototype
if (!tableInfo.isPrototype()) {
// Break the path into the individual structure variable references
String[] ancestors = tableInfo.getTablePath().split(",");
// table
for (int index = ancestors.length - 1; index >= 0 && !cancelImport; index--) {
// Split the ancestor into the data type (i.e., structure name) and
// variable name
String[] typeAndVar = ancestors[index].split("\\.");
// Check if the ancestor prototype table doesn't exist
if (!dbTable.isTableExists(typeAndVar[0].toLowerCase(), ccddMain.getMainFrame())) {
// Create the table information for the new prototype table
TableInformation ancestorInfo = new TableInformation(tableDefn.getTypeName(), typeAndVar[0], new String[0][0], tableTypeHandler.getDefaultColumnOrder(tableDefn.getTypeName()), "", true, tableDefn.getDataFields().toArray(new String[0][0]));
// Check if this is the child table and not one of its ancestors
if (index == ancestors.length - 1) {
// Create a list to store a copy of the cell data
List<String> protoData = new ArrayList<String>(tableDefn.getData());
// Step through each row of the cell data
for (int cellIndex = 0; cellIndex < tableDefn.getData().size(); cellIndex += numColumns) {
// Step through each column in the row
for (int colIndex = 0; colIndex < numColumns; colIndex++) {
// type
if (!DefaultColumn.isTypeRequiredColumn((typeDefn.isStructure() ? TYPE_STRUCTURE : (typeDefn.isCommand() ? TYPE_COMMAND : TYPE_OTHER)), typeDefn.getInputTypesVisible()[colIndex])) {
// Replace the non-required column value with a
// blank. The child's non-required values are
// therefore not inherited from the prototype
protoData.set(cellIndex + colIndex, "");
}
}
}
// the protected column data
if (!createImportedTable(ancestorInfo, protoData, numColumns, replaceExisting, "Cannot create prototype '" + ancestorInfo.getPrototypeName() + "' of child table", allTables, parent)) {
// Add the skipped table to the list
skippedTables.add(ancestorInfo.getTablePath());
}
} else // This is an ancestor of the child table
{
// Split the ancestor into the data type (i.e., structure name)
// and variable name
typeAndVar = ancestors[index + 1].split("\\.|$", -1);
// Add the variable reference to the new table
String[] rowData = new String[typeDefn.getColumnCountVisible()];
Arrays.fill(rowData, "");
rowData[typeDefn.getVisibleColumnIndexByUserName(typeDefn.getColumnNameByInputType(InputDataType.VARIABLE))] = typeAndVar[1];
rowData[typeDefn.getVisibleColumnIndexByUserName(typeDefn.getColumnNameByInputType(InputDataType.PRIM_AND_STRUCT))] = typeAndVar[0];
// the protected column data
if (!createImportedTable(ancestorInfo, Arrays.asList(rowData), numColumns, replaceExisting, "Cannot create prototype '" + ancestorInfo.getPrototypeName() + "' of child table's ancestor", allTables, parent)) {
// Add the skipped table to the list
skippedTables.add(ancestorInfo.getTablePath());
}
}
}
}
// Load the table's prototype data from the database and copy the
// prototype's data to the table
TableInformation protoInfo = dbTable.loadTableData(tableInfo.getPrototypeName(), false, false, false, ccddMain.getMainFrame());
tableInfo.setData(protoInfo.getData());
}
// Create a table from the imported information
if (!createImportedTable(tableInfo, tableDefn.getData(), numColumns, replaceExisting, "Cannot create prototype '" + tableInfo.getPrototypeName() + "'", allTables, parent)) {
// Add the skipped table to the list
skippedTables.add(tableInfo.getTablePath());
}
}
}
prototypesOnly = false;
}
// Check if any tables were skipped
if (!skippedTables.isEmpty()) {
// Inform the user that one or more tables were not imported
new CcddDialogHandler().showMessageDialog(parent, "<html><b>Table(s) not imported<br>'</b>" + dbTable.getShortenedTableNames(skippedTables.toArray(new String[0])) + "<b>';<br>table already exists", "Import Warning", JOptionPane.WARNING_MESSAGE, DialogOption.OK_OPTION);
}
// Store the table types
dbTable.storeInformationTable(InternalTable.TABLE_TYPES, null, null, parent);
// Store the data types
dbTable.storeInformationTable(InternalTable.DATA_TYPES, CcddUtilities.removeArrayListColumn(dataTypeHandler.getDataTypeData(), DataTypesColumn.OID.ordinal()), null, parent);
// Check if any macros are defined
if (!macroHandler.getMacroData().isEmpty()) {
// Store the macros in the database
dbTable.storeInformationTable(InternalTable.MACROS, CcddUtilities.removeArrayListColumn(macroHandler.getMacroData(), MacrosColumn.OID.ordinal()), null, parent);
}
// Check if any reserved message IDs are defined
if (!rsvMsgIDHandler.getReservedMsgIDData().isEmpty()) {
// Store the reserved message IDs in the database
dbTable.storeInformationTable(InternalTable.RESERVED_MSG_IDS, CcddUtilities.removeArrayListColumn(rsvMsgIDHandler.getReservedMsgIDData(), ReservedMsgIDsColumn.OID.ordinal()), null, parent);
}
}
use of CCDD.CcddClassesDataTable.CCDDException in project CCDD by nasa.
the class CcddFileIOHandler method importSelectedFileIntoTable.
/**
********************************************************************************************
* Import the contents of a file selected by the user into the specified existing table
*
* @param tableHandler
* reference to the table handler for the table into which to import the data
********************************************************************************************
*/
protected void importSelectedFileIntoTable(CcddTableEditorHandler tableHandler) {
// Set the initial layout manager characteristics
GridBagConstraints gbc = new GridBagConstraints(0, 0, 1, 1, 1.0, 0.0, GridBagConstraints.LINE_START, GridBagConstraints.BOTH, new Insets(ModifiableSpacingInfo.LABEL_VERTICAL_SPACING.getSpacing() / 2, ModifiableSpacingInfo.LABEL_HORIZONTAL_SPACING.getSpacing() / 2, 0, 0), 0, 0);
// Create an empty border
Border emptyBorder = BorderFactory.createEmptyBorder();
// Create overwrite check box
JCheckBox overwriteChkBx = new JCheckBox("Overwrite existing cells");
overwriteChkBx.setFont(ModifiableFontInfo.LABEL_BOLD.getFont());
overwriteChkBx.setBorder(emptyBorder);
overwriteChkBx.setToolTipText(CcddUtilities.wrapText("Overwrite existing cell data; if unchecked then new " + "rows are inserted to contain the imported data", ModifiableSizeInfo.MAX_TOOL_TIP_LENGTH.getSize()));
overwriteChkBx.setSelected(false);
// Create a check box for indicating existing tables can be replaced
JCheckBox useExistingFieldsCb = new JCheckBox("Use existing field if duplicate");
useExistingFieldsCb.setFont(ModifiableFontInfo.LABEL_BOLD.getFont());
useExistingFieldsCb.setBorder(emptyBorder);
useExistingFieldsCb.setToolTipText(CcddUtilities.wrapText("Use the existing data field definition if " + "a field with the same name is imported", ModifiableSizeInfo.MAX_TOOL_TIP_LENGTH.getSize()));
useExistingFieldsCb.setSelected(true);
// Create a panel to contain the overwrite check box
JPanel checkBoxPnl = new JPanel(new GridBagLayout());
checkBoxPnl.setBorder(emptyBorder);
checkBoxPnl.add(overwriteChkBx, gbc);
gbc.insets.top = ModifiableSpacingInfo.LABEL_VERTICAL_SPACING.getSpacing();
gbc.gridy++;
checkBoxPnl.add(useExistingFieldsCb, gbc);
// Allow the user to select the data file path + name to import from
FileEnvVar[] dataFile = new CcddDialogHandler().choosePathFile(ccddMain, tableHandler.getOwner(), null, "export", new FileNameExtensionFilter[] { new FileNameExtensionFilter(FileExtension.CSV.getDescription(), FileExtension.CSV.getExtensionName()), new FileNameExtensionFilter(FileExtension.EDS.getDescription(), FileExtension.EDS.getExtensionName()), new FileNameExtensionFilter(FileExtension.JSON.getDescription(), FileExtension.JSON.getExtensionName()), new FileNameExtensionFilter(FileExtension.XTCE.getDescription(), FileExtension.XTCE.getExtensionName()) }, false, false, "Import Table Data", ccddMain.getProgPrefs().get(ModifiablePathInfo.TABLE_EXPORT_PATH.getPreferenceKey(), null), DialogOption.IMPORT_OPTION, checkBoxPnl);
// Check if a file was chosen
if (dataFile != null && dataFile[0] != null) {
try {
List<TableDefinition> tableDefinitions = null;
CcddImportExportInterface ioHandler = null;
// Check if the file to import is in CSV format based on the extension
if (dataFile[0].getAbsolutePath().endsWith(FileExtension.CSV.getExtension())) {
// Create a CSV handler
ioHandler = new CcddCSVHandler(ccddMain, tableHandler.getFieldHandler(), tableHandler.getOwner());
} else // Check if the file to import is in EDS XML format based on the extension
if (dataFile[0].getAbsolutePath().endsWith(FileExtension.EDS.getExtension())) {
// Create an EDS handler
ioHandler = new CcddEDSHandler(ccddMain, tableHandler.getFieldHandler(), tableHandler.getOwner());
} else // Check if the file to import is in JSON format based on the extension
if (dataFile[0].getAbsolutePath().endsWith(FileExtension.JSON.getExtension())) {
// Create a JSON handler
ioHandler = new CcddJSONHandler(ccddMain, tableHandler.getFieldHandler(), tableHandler.getOwner());
} else // Check if the file to import is in XTCE XML format based on the extension
if (dataFile[0].getAbsolutePath().endsWith(FileExtension.XTCE.getExtension())) {
// Create an XTCE handler
ioHandler = new CcddXTCEHandler(ccddMain, tableHandler.getFieldHandler(), tableHandler.getOwner());
} else // The file extension isn't recognized
{
throw new CCDDException("Cannot import file '" + dataFile[0].getAbsolutePath() + "' into table; unrecognized file type");
}
// Check that no error occurred creating the format conversion handler
if (!ioHandler.getErrorStatus()) {
// Store the current table type information so that it can be restored
List<TypeDefinition> originalTableTypes = tableTypeHandler.getTypeDefinitions();
// Import the data file into a table definition
ioHandler.importFromFile(dataFile[0], ImportType.FIRST_DATA_ONLY);
tableDefinitions = ioHandler.getTableDefinitions();
// Check if a table definition was successfully created
if (tableDefinitions != null && !tableDefinitions.isEmpty()) {
// Get a short-cut to the table definition to shorten subsequent calls
TableDefinition tableDefn = tableDefinitions.get(0);
// End any active edit sequence, then disable auto-ending so that the
// import operation can be handled as a single edit for undo/redo purposes
tableHandler.getTable().getUndoManager().endEditSequence();
tableHandler.getTable().getUndoHandler().setAutoEndEditSequence(false);
// Update the table description field in case the description changed
tableHandler.setDescription(tableDefn.getDescription());
// Add the imported data field(s) to the table
addImportedDataField(tableHandler.getFieldHandler(), tableDefn, tableHandler.getTableInformation().getTablePath(), useExistingFieldsCb.isSelected());
// Update the field information in case the field values changed
tableHandler.getFieldHandler().setFieldDefinitions(tableDefn.getDataFields());
tableHandler.getFieldHandler().buildFieldInformation(tableHandler.getTableInformation().getTablePath());
// Rebuild the table's editor panel which contains the data fields
tableHandler.createDataFieldPanel(true);
// Check if cell data is provided in the table definition
if (tableDefn.getData() != null && !tableDefn.getData().isEmpty()) {
// Get the original number of rows in the table
int numRows = tableHandler.getTableModel().getRowCount();
// importing the table following a cell validation error
if (!tableHandler.getTable().pasteData(tableDefn.getData().toArray(new String[0]), tableHandler.getTable().getColumnCount(), !overwriteChkBx.isSelected(), !overwriteChkBx.isSelected(), true, false)) {
// Let the user know how many rows were added
new CcddDialogHandler().showMessageDialog(tableHandler.getOwner(), "<html><b>" + (tableHandler.getTableModel().getRowCount() - numRows) + " row(s) added", "Paste Table Data", JOptionPane.INFORMATION_MESSAGE, DialogOption.OK_OPTION);
}
}
// Restore the table types to the values prior to the import operation
tableTypeHandler.setTypeDefinitions(originalTableTypes);
// Re-enable auto-ending of the edit sequence and end the sequence. The
// imported data can be removed with a single undo if desired
tableHandler.getTable().getUndoHandler().setAutoEndEditSequence(true);
tableHandler.getTable().getUndoManager().endEditSequence();
// Store the data file path in the program preferences backing store
storePath(ccddMain, dataFile[0].getAbsolutePathWithEnvVars(), true, ModifiablePathInfo.TABLE_EXPORT_PATH);
}
}
} catch (IOException ioe) {
// Inform the user that the data file cannot be read
new CcddDialogHandler().showMessageDialog(tableHandler.getOwner(), "<html><b>Cannot read import file<br>'</b>" + dataFile[0].getAbsolutePath() + "<b>'", "File Error", JOptionPane.ERROR_MESSAGE, DialogOption.OK_OPTION);
} catch (CCDDException ce) {
// Check if an error message is provided
if (!ce.getMessage().isEmpty()) {
// Inform the user that an error occurred reading the import file
new CcddDialogHandler().showMessageDialog(tableHandler.getOwner(), "<html><b>" + ce.getMessage(), "File Error", ce.getMessageType(), DialogOption.OK_OPTION);
}
} catch (Exception e) {
// Display a dialog providing details on the unanticipated error
CcddUtilities.displayException(e, tableHandler.getOwner());
}
}
}
Aggregations