# HG changeset patch # User matthias42@netbeans.org # Date 1324669084 -3600 # Node ID b89bec05fd743dae6ac783ea04afa0b36bbd84b6 # Parent 2f9d25905b685ade10013228e0ecf543f5dbfee0 1. Move XML Parsing to JAXB instead of lowlevel SAX 2. Unify persistence handling into SQLHistoryManager and get rid of the Persistence Manager 3. Let the SQLHistory expose its structure as a Set, which makes it more convenient to manipulate the contents. 4. Clean up the SQLHistoryPanel: -> use less classes to implement the panel -> clean the HistoryTableModel -> use Swing RowSorter/RowFilter for the designated tasks diff --git a/db.core/src/org/netbeans/modules/db/sql/execute/SQLExecuteHelper.java b/db.core/src/org/netbeans/modules/db/sql/execute/SQLExecuteHelper.java --- a/db.core/src/org/netbeans/modules/db/sql/execute/SQLExecuteHelper.java +++ b/db.core/src/org/netbeans/modules/db/sql/execute/SQLExecuteHelper.java @@ -44,7 +44,7 @@ package org.netbeans.modules.db.sql.execute; -import org.netbeans.modules.db.sql.history.SQLHistory; +import org.netbeans.modules.db.sql.history.SQLHistoryEntry; import java.util.ArrayList; import java.util.Collections; import java.util.Date; @@ -54,8 +54,6 @@ import org.netbeans.api.db.explorer.DatabaseConnection; import org.netbeans.modules.db.dataview.api.DataView; import org.netbeans.modules.db.sql.history.SQLHistoryManager; -import org.openide.filesystems.FileObject; -import org.openide.filesystems.FileUtil; /** * Support class for executing SQL statements. @@ -68,7 +66,6 @@ private static final Logger LOGGER = Logger.getLogger(SQLExecuteHelper.class.getName()); private static final boolean LOG = LOGGER.isLoggable(Level.FINE); - private static final FileObject USERDIR = FileUtil.getConfigRoot(); /** * Executes a SQL string, possibly containing multiple statements. Returns the execution @@ -119,7 +116,7 @@ DataView view = DataView.create(conn, sql, pageSize); // Save SQL statements executed for the SQLHistoryManager - SQLHistoryManager.getInstance().saveSQL(new SQLHistory(url, sql, new Date())); + SQLHistoryManager.getInstance().saveSQL(new SQLHistoryEntry(url, sql, new Date())); result = new SQLExecutionResult(info, view); @@ -153,7 +150,7 @@ } // Persist SQL executed - SQLHistoryManager.getInstance().save(USERDIR); + SQLHistoryManager.getInstance().save(); if (!cancelled) { return new SQLExecutionResults(results); diff --git a/db.core/src/org/netbeans/modules/db/sql/execute/ui/SQLHistoryPanel.form b/db.core/src/org/netbeans/modules/db/sql/execute/ui/SQLHistoryPanel.form --- a/db.core/src/org/netbeans/modules/db/sql/execute/ui/SQLHistoryPanel.form +++ b/db.core/src/org/netbeans/modules/db/sql/execute/ui/SQLHistoryPanel.form @@ -21,11 +21,11 @@ - + - + @@ -65,7 +65,7 @@ - + @@ -90,11 +90,6 @@ - - - - - @@ -163,37 +158,24 @@ + - + - - - - - <Editor/> - <Renderer/> - </Column> - <Column maxWidth="-1" minWidth="-1" prefWidth="-1" resizable="true"> - <Title/> - <Editor/> - <Renderer/> - </Column> - </TableColumnModel> - </Property> - <Property name="gridColor" type="java.awt.Color" editor="org.netbeans.beaninfo.editors.ColorEditor"> - <Color blue="c0" green="c0" id="lightGray" palette="1" red="c0" type="palette"/> + <Property name="tableHeader" type="javax.swing.table.JTableHeader" editor="org.netbeans.modules.form.editors2.JTableHeaderEditor"> + <TableHeader reorderingAllowed="true" resizingAllowed="true"/> </Property> </Properties> <AccessibilityProperties> <Property name="AccessibleContext.accessibleName" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> <ResourceString bundle="org/netbeans/modules/db/sql/execute/ui/Bundle.properties" key="ACSN_History" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/> </Property> - <Property name="AccessibleContext.accessibleDescription" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <Property name="AccessibleContext.accessibleDescription" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor" postCode="int dateColumnWidth1 = new JTextField(dateTimeFormat.format(new Date())).getPreferredSize().width; int dateColumnWidth2 = new JTextField(NbBundle.getMessage(SQLHistoryPanel.class, "LBL_DateTableTitle") + "XXXXX").getPreferredSize().width; int dateColumnWidth = Math.max(dateColumnWidth1, dateColumnWidth2); TableColumnModel sqlHistoryTableTCM = sqlHistoryTable.getColumnModel(); TableColumn sqlHistoryTableColumn; sqlHistoryTableColumn = new TableColumn(1); sqlHistoryTableColumn.setHeaderValue(NbBundle.getMessage(SQLHistoryPanel.class, "LBL_SQLTableTitle")); sqlHistoryTableTCM.addColumn(sqlHistoryTableColumn); sqlHistoryTableColumn = new TableColumn(2); sqlHistoryTableColumn.setMinWidth(dateColumnWidth); sqlHistoryTableColumn.setPreferredWidth(dateColumnWidth); sqlHistoryTableColumn.setMaxWidth(dateColumnWidth); sqlHistoryTableColumn.setHeaderValue(NbBundle.getMessage(SQLHistoryPanel.class, "LBL_DateTableTitle")); sqlHistoryTableColumn.setCellRenderer(new DefaultTableCellRenderer() { public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) { if(value instanceof Date) { value = dateTimeFormat.format((Date) value); } return super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column); } }); sqlHistoryTableTCM.addColumn(sqlHistoryTableColumn);"> <ResourceString bundle="org/netbeans/modules/db/sql/execute/ui/Bundle.properties" key="ACSD_History" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/> </Property> </AccessibilityProperties> <AuxValues> - <AuxValue name="JavaCodeGenerator_CreateCodeCustom" type="java.lang.String" value="new JTable() { public Component prepareRenderer(TableCellRenderer renderer, int rowIndex, int vColIndex) { Component c = super.prepareRenderer(renderer, rowIndex, vColIndex); if (c instanceof JComponent) { JComponent jc = (JComponent)c; jc.setToolTipText(view.getSQLHistoryTooltipValue(rowIndex, vColIndex)); } return c; } };"/> + <AuxValue name="JavaCodeGenerator_CreateCodeCustom" type="java.lang.String" value="new JTable() { public Component prepareRenderer(TableCellRenderer renderer, int rowIndex, int vColIndex) { Component c = super.prepareRenderer(renderer, rowIndex, vColIndex); if (c instanceof JComponent) { JComponent jc = (JComponent)c; jc.setToolTipText(getSQLHistoryTooltipValue(sqlHistoryTable, rowIndex, vColIndex)); } return c; } }"/> </AuxValues> </Component> </SubComponents> @@ -214,7 +196,7 @@ <Component class="javax.swing.JTextField" name="sqlLimitTextField"> <Properties> <Property name="text" type="java.lang.String" editor="org.netbeans.modules.form.RADConnectionPropertyEditor"> - <Connection code="SQLHistoryManager.SAVE_STATEMENTS_MAX_LIMIT_ENTERED" type="code"/> + <Connection code="Integer.toString(SQLHistoryManager.getInstance().getListSize())" type="code"/> </Property> <Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> <Dimension value="[18, 22]"/> @@ -224,7 +206,7 @@ <Property name="AccessibleContext.accessibleName" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> <ResourceString bundle="org/netbeans/modules/db/sql/execute/ui/Bundle.properties" key="ACSN_Save" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/> </Property> - <Property name="AccessibleContext.accessibleDescription" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <Property name="AccessibleContext.accessibleDescription" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor" postCode="sqlLimitTextField.setInputVerifier(new InputVerifier() { public boolean verify(JComponent input) { JTextField tf = (JTextField) input; return tf.getText().matches("^\\d+$"); } });"> <ResourceString bundle="org/netbeans/modules/db/sql/execute/ui/Bundle.properties" key="ACSD_Save" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/> </Property> </AccessibilityProperties> diff --git a/db.core/src/org/netbeans/modules/db/sql/execute/ui/SQLHistoryPanel.java b/db.core/src/org/netbeans/modules/db/sql/execute/ui/SQLHistoryPanel.java --- a/db.core/src/org/netbeans/modules/db/sql/execute/ui/SQLHistoryPanel.java +++ b/db.core/src/org/netbeans/modules/db/sql/execute/ui/SQLHistoryPanel.java @@ -39,7 +39,6 @@ * * Portions Copyrighted 2009 - 2010 Sun Microsystems, Inc. */ - /* * SQLHistoryPanel.java * @@ -48,252 +47,171 @@ package org.netbeans.modules.db.sql.execute.ui; import java.awt.Component; -import java.awt.Cursor; -import java.awt.Window; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; -import java.awt.event.WindowAdapter; -import java.awt.event.WindowEvent; import java.text.DateFormat; import java.util.ArrayList; -import java.util.Collections; -import java.util.Comparator; import java.util.Date; -import java.util.HashMap; -import java.util.HashSet; import java.util.List; -import java.util.Map; -import java.util.Set; import java.util.logging.Level; import java.util.logging.Logger; import javax.swing.DefaultComboBoxModel; -import javax.swing.DefaultListCellRenderer; +import javax.swing.InputVerifier; import javax.swing.JComponent; import javax.swing.JEditorPane; -import javax.swing.JLabel; -import javax.swing.JList; import javax.swing.JTable; -import javax.swing.SwingUtilities; -import javax.swing.UIManager; +import javax.swing.JTextField; +import javax.swing.ListSelectionModel; +import javax.swing.RowFilter; +import javax.swing.RowFilter.Entry; +import javax.swing.RowSorter.SortKey; +import javax.swing.SortOrder; import javax.swing.event.DocumentEvent; import javax.swing.event.DocumentListener; +import javax.swing.event.ListSelectionEvent; +import javax.swing.event.ListSelectionListener; import javax.swing.event.TableModelEvent; import javax.swing.event.TableModelListener; +import javax.swing.table.AbstractTableModel; import javax.swing.table.DefaultTableCellRenderer; -import javax.swing.table.DefaultTableModel; -import javax.swing.table.JTableHeader; import javax.swing.table.TableCellRenderer; import javax.swing.table.TableColumn; import javax.swing.table.TableColumnModel; +import javax.swing.table.TableRowSorter; import javax.swing.text.BadLocationException; import javax.swing.text.Caret; import javax.swing.text.Document; -import org.netbeans.api.db.explorer.ConnectionManager; -import org.netbeans.api.db.explorer.DatabaseConnection; import org.netbeans.api.editor.EditorRegistry; -import org.netbeans.modules.db.sql.history.SQLHistory; -import org.netbeans.modules.db.sql.history.SQLHistoryException; +import org.netbeans.modules.db.sql.history.SQLHistoryEntry; import org.netbeans.modules.db.sql.history.SQLHistoryManager; -import org.netbeans.modules.db.sql.history.SQLHistoryModel; -import org.netbeans.modules.db.sql.history.SQLHistoryModelImpl; -import org.netbeans.modules.db.sql.history.SQLHistoryPersistenceManager; import org.netbeans.modules.db.sql.loader.SQLDataLoader; import org.openide.awt.MouseUtils; -import org.openide.filesystems.FileObject; -import org.openide.filesystems.FileUtil; import org.openide.util.Exceptions; import org.openide.util.NbBundle; -import org.openide.util.NbPreferences; -import org.openide.util.RequestProcessor; -import org.openide.util.RequestProcessor.Task; +import org.openide.util.NotImplementedException; /** * * @author John Baker */ public class SQLHistoryPanel extends javax.swing.JPanel { + + private TableRowSorter<HistoryTableModel> rowSorter; + private HistoryTableModel htm = new HistoryTableModel(); public static final String SAVE_STATEMENTS_CLEARED = ""; // NOI18N - public static final int SAVE_STATEMENTS_MAX_LIMIT = 10000; - public static final int TABLE_DATA_WIDTH_SQL = 125; public static final Logger LOGGER = Logger.getLogger(SQLHistoryPanel.class.getName()); - private static final FileObject USERDIR = FileUtil.getConfigRoot(); - private static final FileObject historyRoot = USERDIR.getFileObject(SQLHistoryManager.SQL_HISTORY_FOLDER); - private static Object[][] data; - private Set<String> currentConnections = new HashSet<String>(); - private SQLHistoryView view; private JEditorPane editorPane; - private Map<String,String> urlAliasMap = new HashMap<String, String>(); - private Map<String,String> aliasUrlMap = new HashMap<String, String>(); - private static RequestProcessor RP = new RequestProcessor(SQLHistoryPanel.class); - private final Task initTask; + final private ListSelectionModel sqlTableSelektion; + final private DateFormat dateTimeFormat = DateFormat.getDateTimeInstance(DateFormat.SHORT, DateFormat.SHORT); /** Creates new form SQLHistoryPanel */ public SQLHistoryPanel(final JEditorPane editorPane) { this.editorPane = editorPane; - // dummy model - view = new SQLHistoryView(new SQLHistoryModel() { + initComponents(); + + rowSorter = new TableRowSorter<HistoryTableModel>(htm); + sqlHistoryTable.setRowSorter(rowSorter); + List<SortKey> sortKeys = new ArrayList<SortKey>(); + sortKeys.add(new SortKey(2, SortOrder.DESCENDING)); + rowSorter.setSortKeys(sortKeys); + rowSorter.setSortsOnUpdates(true); + rowSorter.sort(); + + sqlTableSelektion = sqlHistoryTable.getSelectionModel(); + + updateURLList(); + + htm.addTableModelListener(new TableModelListener() { @Override - public void initialize() { + public void tableChanged(TableModelEvent e) { + updateURLList(); + } + }); + + searchTextField.getDocument().addDocumentListener(new DocumentListener() { + + @Override + public void insertUpdate(DocumentEvent e) { + updateFilter(); } @Override - public void setFilter(String filter) { + public void removeUpdate(DocumentEvent e) { + updateFilter(); } @Override - public String getFilter() { - return ""; // NOI18N - } - - @Override - public List<SQLHistory> getSQLHistoryList() throws SQLHistoryException { - return Collections.emptyList(); - } - - @Override - public void setSQLHistoryList(List<SQLHistory> sqlHistoryList) { + public void changedUpdate(DocumentEvent e) { + updateFilter(); } }); - initSQLHistoryTableData(); - initComponents(); - setupSQLSaveLimit(); - initTask = RP.post(new Runnable() { + sqlHistoryTable.addMouseListener(new MouseAdapter() { @Override - public void run() { - lazyInit(); - } - }); - } - - public void lazyInit() { - view = new SQLHistoryView(new SQLHistoryModelImpl()); - for (DatabaseConnection existingConnection : ConnectionManager.getDefault().getConnections()) { - urlAliasMap.put(existingConnection.getDatabaseURL(), existingConnection.getDisplayName()); - aliasUrlMap.put(existingConnection.getDisplayName(), existingConnection.getDatabaseURL()); - } - // Adjust table column width - SwingUtilities.invokeLater(new Runnable() { - - @Override - public void run() { - setWaitingState(false); - initSQLHistoryTableData(); - initComponentData(); - adjustColumnPreferredWidths(sqlHistoryTable); - sqlHistoryTable.revalidate(); - } - }); - } - - @Override - public void addNotify() { - super.addNotify(); - //show progress for initialize method - final Window w = findWindowParent(); - if (w != null) { - w.addWindowListener(new WindowAdapter() { - - @Override - public void windowOpened(WindowEvent e) { - setWaitingState(! initTask.isFinished()); - } - }); - } - } - - private void setWaitingState(boolean waitingState) { - boolean enabled = !waitingState; - Component parent = getParent(); - Component rootPane = getRootPane(); - if (parent != null) { - parent.setEnabled(enabled); - } - if (rootPane != null) { - if (enabled) { - rootPane.setCursor(null); - } else { - rootPane.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR)); - } - } - } - - private Window findWindowParent() { - Component c = this; - while (c != null) { - c = c.getParent(); - if (c instanceof Window) { - return (Window) c; - } - } - return null; - } - - private void setupSQLSaveLimit() { - // SQL statments save limit - String savedLimit = NbPreferences.forModule(SQLHistoryPanel.class).get("SQL_STATEMENTS_SAVED_FOR_HISTORY", ""); // NOI18N - if (null != savedLimit && !savedLimit.equals(SAVE_STATEMENTS_CLEARED)) { - sqlLimitTextField.setText(savedLimit); - } else { - sqlLimitTextField.setText(SQLHistoryManager.SAVE_STATEMENTS_MAX_LIMIT_ENTERED); - savedLimit = SQLHistoryManager.SAVE_STATEMENTS_MAX_LIMIT_ENTERED; - NbPreferences.forModule(SQLHistoryPanel.class).put("SQL_STATEMENTS_SAVED_FOR_HISTORY", SQLHistoryManager.SAVE_STATEMENTS_MAX_LIMIT_ENTERED); // NOI18N - } - } - - private void initComponentData() { - searchTextField.getDocument().addDocumentListener((HistoryTableModel) sqlHistoryTable.getModel()); - sqlHistoryTable.getColumnModel().getColumn(0).setHeaderValue(NbBundle.getMessage(SQLHistoryPanel.class, "LBL_SQLTableTitle")); - sqlHistoryTable.getColumnModel().getColumn(1).setHeaderValue(NbBundle.getMessage(SQLHistoryPanel.class, "LBL_DateTableTitle")); - // Add mouse listener to listen for mouse click on the table header so columns can be sorted - JTableHeader header = sqlHistoryTable.getTableHeader(); - header.addMouseListener(new ColumnListener()); - - // Add mouse listener for the case when a user double-clicks on a row to insert SQL - sqlHistoryTable.addMouseListener(new MouseAdapter() { - @Override public void mouseClicked(MouseEvent e) { if (MouseUtils.isDoubleClick(e)) { insertSQL(); e.consume(); + } + } + }); + + sqlTableSelektion.addListSelectionListener( + new ListSelectionListener() { + + @Override + public void valueChanged(ListSelectionEvent e) { + if (sqlTableSelektion.isSelectionEmpty()) { + insertSQLButton.setEnabled(false); + } else { + insertSQLButton.setEnabled(true); + } + } + }); + + connectionUrlComboBox.addActionListener(new ActionListener() { + + @Override + public void actionPerformed(ActionEvent e) { + updateFilter(); + } + }); + } + + private void updateFilter() { + List<RowFilter<HistoryTableModel, Integer>> rowFilter = new ArrayList<RowFilter<HistoryTableModel, Integer>>(); + + String url = (String) connectionUrlComboBox.getSelectedItem(); + + if ( url != null && !url.equals(NbBundle.getMessage(SQLHistoryPanel.class, "LBL_URLComboBoxAllConnectionsItem"))) { + rowFilter.add(new EqualsFilter(url, 0)); + } + + if (!searchTextField.getText().equals("")) { + rowFilter.add(new ContainsInsensitiveFilter(searchTextField.getText(), 1)); + } + + if (rowFilter.size() > 0) { + rowSorter.setRowFilter(RowFilter.andFilter(rowFilter)); + } else { + rowSorter.setRowFilter(null); } } - }); - // Initialize sql column data - connectionUrlComboBox.addActionListener((HistoryTableModel) sqlHistoryTable.getModel()); - view.updateConnectionUrl(); - } - - private void initSQLHistoryTableData() { - if (initTask == null || ! initTask.isFinished()) { - data = new Object[1][2]; - data[0][0] = NbBundle.getMessage(SQLHistoryPanel.class, "SQLHistoryPanel_PleaseWait"); - return ; - } - // Initialize sql column data - List<String> sqlList = view.getSQLList(null); - List<String> dateList = view.getDateList(null); - data = new Object[sqlList.size()][2]; - int row = 0; - int maxLength; - int length; - for (String sql : sqlList) { - length = sql.trim().length(); - maxLength = length > TABLE_DATA_WIDTH_SQL ? TABLE_DATA_WIDTH_SQL : length; - data[row][0] = sql.trim().substring(0, maxLength).replaceAll("\n", " "); - row++; - } - // Initialize data - row = 0; - for (String date : dateList) { - data[row][1] = date; - row++; + private void updateURLList() { + List<String> urls = new ArrayList<String>(htm.getJdbcURLs()); + urls.add(0, NbBundle.getMessage(SQLHistoryPanel.class, "LBL_URLComboBoxAllConnectionsItem")); + Object selected = connectionUrlComboBox.getSelectedItem(); + connectionUrlComboBox.setModel(new DefaultComboBoxModel(urls.toArray())); + if(selected != null && urls.contains(selected)) { + connectionUrlComboBox.setSelectedItem(selected); + } else { + connectionUrlComboBox.setSelectedIndex(0); } } @@ -318,7 +236,7 @@ Component c = super.prepareRenderer(renderer, rowIndex, vColIndex); if (c instanceof JComponent) { JComponent jc = (JComponent)c; - jc.setToolTipText(view.getSQLHistoryTooltipValue(rowIndex, vColIndex)); + jc.setToolTipText(getSQLHistoryTooltipValue(sqlHistoryTable, rowIndex, vColIndex)); } return c; } @@ -330,8 +248,6 @@ jLabel1.setText(org.openide.util.NbBundle.getMessage(SQLHistoryPanel.class, "LBL_Connection")); // NOI18N - connectionUrlComboBox.setRenderer(new ConnectionUrlRenderer()); - jLabel2.setLabelFor(searchTextField); org.openide.awt.Mnemonics.setLocalizedText(jLabel2, org.openide.util.NbBundle.getMessage(SQLHistoryPanel.class, "LBL_Match")); // NOI18N @@ -345,16 +261,44 @@ } }); - sqlHistoryTable.setModel(new HistoryTableModel()); - sqlHistoryTable.setGridColor(java.awt.Color.lightGray); + sqlHistoryTable.setAutoCreateColumnsFromModel(false); + sqlHistoryTable.setModel(htm); jScrollPane1.setViewportView(sqlHistoryTable); sqlHistoryTable.getAccessibleContext().setAccessibleName(org.openide.util.NbBundle.getMessage(SQLHistoryPanel.class, "ACSN_History")); // NOI18N sqlHistoryTable.getAccessibleContext().setAccessibleDescription(org.openide.util.NbBundle.getMessage(SQLHistoryPanel.class, "ACSD_History")); // NOI18N + int dateColumnWidth1 = new JTextField(dateTimeFormat.format(new Date())).getPreferredSize().width; + int dateColumnWidth2 = new JTextField(NbBundle.getMessage(SQLHistoryPanel.class, "LBL_DateTableTitle") + "XXXXX").getPreferredSize().width; + int dateColumnWidth = Math.max(dateColumnWidth1, dateColumnWidth2); + + TableColumnModel sqlHistoryTableTCM = sqlHistoryTable.getColumnModel(); + + TableColumn sqlHistoryTableColumn; + + sqlHistoryTableColumn = new TableColumn(1); + sqlHistoryTableColumn.setHeaderValue(NbBundle.getMessage(SQLHistoryPanel.class, "LBL_SQLTableTitle")); + + sqlHistoryTableTCM.addColumn(sqlHistoryTableColumn); + + sqlHistoryTableColumn = new TableColumn(2); + sqlHistoryTableColumn.setMinWidth(dateColumnWidth); + sqlHistoryTableColumn.setPreferredWidth(dateColumnWidth); + sqlHistoryTableColumn.setMaxWidth(dateColumnWidth); + sqlHistoryTableColumn.setHeaderValue(NbBundle.getMessage(SQLHistoryPanel.class, "LBL_DateTableTitle")); + sqlHistoryTableColumn.setCellRenderer(new DefaultTableCellRenderer() { + public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) { + if(value instanceof Date) { + value = dateTimeFormat.format((Date) value); + } + return super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column); + } + }); + + sqlHistoryTableTCM.addColumn(sqlHistoryTableColumn); sqlLimitLabel.setLabelFor(sqlLimitTextField); org.openide.awt.Mnemonics.setLocalizedText(sqlLimitLabel, org.openide.util.NbBundle.getMessage(SQLHistoryPanel.class, "LBL_SqlLimit")); // NOI18N - sqlLimitTextField.setText(SQLHistoryManager.SAVE_STATEMENTS_MAX_LIMIT_ENTERED); + sqlLimitTextField.setText(Integer.toString(SQLHistoryManager.getInstance().getListSize())); sqlLimitTextField.setMinimumSize(new java.awt.Dimension(18, 22)); org.openide.awt.Mnemonics.setLocalizedText(sqlLimitButton, org.openide.util.NbBundle.getMessage(SQLHistoryPanel.class, "LBL_ApplyButton")); // NOI18N @@ -378,11 +322,11 @@ .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(layout.createSequentialGroup() .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 655, Short.MAX_VALUE) + .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 645, Short.MAX_VALUE) .addGroup(layout.createSequentialGroup() .addComponent(jLabel1) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) - .addComponent(connectionUrlComboBox, 0, 306, Short.MAX_VALUE) + .addComponent(connectionUrlComboBox, 0, 301, Short.MAX_VALUE) .addGap(18, 18, 18) .addComponent(jLabel2) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) @@ -413,7 +357,7 @@ .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addComponent(insertSQLButton) .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup() - .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 168, Short.MAX_VALUE) + .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 268, Short.MAX_VALUE) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) .addComponent(sqlLimitTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) @@ -432,6 +376,13 @@ insertSQLButton.getAccessibleContext().setAccessibleDescription(org.openide.util.NbBundle.getMessage(SQLHistoryPanel.class, "ACSD_Insert")); // NOI18N sqlLimitTextField.getAccessibleContext().setAccessibleName(org.openide.util.NbBundle.getMessage(SQLHistoryPanel.class, "ACSN_Save")); // NOI18N sqlLimitTextField.getAccessibleContext().setAccessibleDescription(org.openide.util.NbBundle.getMessage(SQLHistoryPanel.class, "ACSD_Save")); // NOI18N + sqlLimitTextField.setInputVerifier(new InputVerifier() { + + public boolean verify(JComponent input) { + JTextField tf = (JTextField) input; + return tf.getText().matches("^\\d+$"); + } + }); sqlLimitButton.getAccessibleContext().setAccessibleName(org.openide.util.NbBundle.getMessage(SQLHistoryPanel.class, "ACSN_Apply")); // NOI18N sqlLimitButton.getAccessibleContext().setAccessibleDescription(org.openide.util.NbBundle.getMessage(SQLHistoryPanel.class, "ACSD_Apply")); // NOI18N }// </editor-fold>//GEN-END:initComponents @@ -444,122 +395,90 @@ verifySQLLimit(); }//GEN-LAST:event_sqlLimitButtonActionPerformed - private void insertSQL() { try { - // Make sure to insert the entire SQL, not just what appears in the Table - List<SQLHistory> sqlHistoryList = view.getCurrentSQLHistoryList(); - int i = 0; - String sqlToInsert = ""; // NOI18N - InsertSQLUtility insertUtility = new InsertSQLUtility(); - for (SQLHistory sqlHistory : sqlHistoryList) { - if (sqlHistoryTable.isRowSelected(i)) { - sqlToInsert = sqlHistory.getSql().trim(); - JEditorPane pane = (JEditorPane)EditorRegistry.lastFocusedComponent(); + JEditorPane pane = (JEditorPane) EditorRegistry.lastFocusedComponent(); String mime = pane.getContentType(); if (mime.equals(SQLDataLoader.SQL_MIME_TYPE)) { editorPane = pane; } - insertUtility.insert(sqlToInsert, editorPane); + int min = sqlTableSelektion.getMinSelectionIndex(); + int max = sqlTableSelektion.getMaxSelectionIndex(); + for (int i = min; i <= max; i++) { + if (sqlHistoryTable.isRowSelected(i)) { + int modelIndex = sqlHistoryTable.convertRowIndexToModel(i); + String sql = ((String) htm.getValueAt(modelIndex, 1)).trim(); + insertIntoDocument(sql, editorPane); } - // increment for the next row - i++; } - } catch (BadLocationException ex) { Exceptions.printStackTrace(ex); } } private void verifySQLLimit() { - String enteredLimit = sqlLimitTextField.getText(); - int iLimit = 0; - if (enteredLimit.equals(SAVE_STATEMENTS_CLEARED)) { - updateSaveLimitUponClear(iLimit); - inputWarningLabel.setText(""); // NOI18N - } else { // user enters a value to limit the number of SQL statements to save - updateSaveLimitUponReset(enteredLimit); + String enteredLimitString = sqlLimitTextField.getText(); + String currentLimit = Integer.toString(SQLHistoryManager.getInstance().getListSize()); + String maxLimit = Integer.toString(SQLHistoryManager.MAX_SQL_STATEMENTS_SAVED_FOR_HISTORY); + if (enteredLimitString.equals(SAVE_STATEMENTS_CLEARED)) { + sqlLimitTextField.setText(currentLimit); + return; + } + try { + Integer enteredLimit = Integer.valueOf(enteredLimitString); + if (enteredLimit > SQLHistoryManager.MAX_SQL_STATEMENTS_SAVED_FOR_HISTORY) { + inputWarningLabel.setText(NbBundle.getMessage(SQLHistoryPanel.class, "LBL_NumberInputWarningLabel")); + sqlLimitTextField.setText(maxLimit); + SQLHistoryManager.getInstance().setListSize(SQLHistoryManager.MAX_SQL_STATEMENTS_SAVED_FOR_HISTORY); + } else { + inputWarningLabel.setText(""); // NOI18N + SQLHistoryManager.getInstance().setListSize(enteredLimit); + } + } catch (NumberFormatException ex) { + inputWarningLabel.setText(NbBundle.getMessage(SQLHistoryPanel.class, "LBL_NumberInputWarningLabel")); + sqlLimitTextField.setText(currentLimit); } - } + htm.refresh(); + } - private void updateSaveLimitUponClear(int iLimit) { - iLimit = SAVE_STATEMENTS_MAX_LIMIT; - List<SQLHistory> sqlHistoryList = new ArrayList<SQLHistory>(); - try { - view.setSQLHistoryList(SQLHistoryPersistenceManager.getInstance().updateSQLSaved(iLimit, historyRoot)); - sqlHistoryList = SQLHistoryPersistenceManager.getInstance().retrieve(historyRoot); - view.setCurrentSQLHistoryList(sqlHistoryList); - } catch (ClassNotFoundException ex) { - Exceptions.printStackTrace(ex); - } catch (SQLHistoryException ex) { - handleSQLHistoryException(); - } - ((HistoryTableModel) sqlHistoryTable.getModel()).refreshTable(sqlHistoryList); - NbPreferences.forModule(SQLHistoryPanel.class).put("SQL_STATEMENTS_SAVED_FOR_HISTORY", Integer.toString(iLimit)); // NOI18N - sqlLimitTextField.setText(SQLHistoryManager.SAVE_STATEMENTS_MAX_LIMIT_ENTERED); - } - - private void updateSaveLimitUponReset(String enteredLimit) { - try { - int iLimit; - if (enteredLimit.trim().length() < 10) { - iLimit = Integer.parseInt(enteredLimit); + public String getSQLHistoryTooltipValue(JTable historyTable, int row, int col) { + HistoryTableModel historyTableModel = (HistoryTableModel) historyTable.getModel(); + int modelColumn = historyTable.convertColumnIndexToModel(col); + int modelRow = historyTable.convertRowIndexToModel(row); + + if (String.class.isAssignableFrom(historyTableModel.getColumnClass(modelColumn))) { + String data = (String) historyTableModel.getValueAt(modelRow, modelColumn); + return "<html>" + data.trim().replace("\n", "<br>") + "</html>"; // NOI18N + } else if (Date.class.isAssignableFrom(historyTableModel.getColumnClass(modelColumn))) { + Date data = (Date) historyTableModel.getValueAt(modelRow, modelColumn); + return DateFormat.getInstance().format(data); } else { - // too long number - iLimit = SAVE_STATEMENTS_MAX_LIMIT + 1; - } - String savedLimit = NbPreferences.forModule(SQLHistoryPanel.class).get("SQL_STATEMENTS_SAVED_FOR_HISTORY", SAVE_STATEMENTS_CLEARED); // NOI18N - if (iLimit < 0) { - inputWarningLabel.setText(NbBundle.getMessage(SQLHistoryPanel.class, "LBL_TextInputWarningLabel")); - if (savedLimit != null) { - sqlLimitTextField.setText(savedLimit); - } else { - sqlLimitTextField.setText(SQLHistoryManager.SAVE_STATEMENTS_MAX_LIMIT_ENTERED); - } - } else if (iLimit > SAVE_STATEMENTS_MAX_LIMIT) { - sqlLimitButton.setEnabled(true); - inputWarningLabel.setText(NbBundle.getMessage(SQLHistoryPanel.class, "LBL_NumberInputWarningLabel")); - // reset user's input - if (savedLimit != null) { - sqlLimitTextField.setText(savedLimit); - } else { - sqlLimitTextField.setText(SAVE_STATEMENTS_CLEARED); - sqlLimitTextField.setText(SQLHistoryManager.SAVE_STATEMENTS_MAX_LIMIT_ENTERED); - } - } else { - inputWarningLabel.setText(""); // NOI18N - if (SQLHistoryPersistenceManager.getInstance().updateSQLSaved(iLimit, historyRoot).size() > 0) { - List<SQLHistory> sqlHistoryList = SQLHistoryPersistenceManager.getInstance().retrieve(historyRoot); - view.setCurrentSQLHistoryList(sqlHistoryList); - ((HistoryTableModel) sqlHistoryTable.getModel()).refreshTable(sqlHistoryList); - view.updateConnectionUrl(); - NbPreferences.forModule(SQLHistoryPanel.class).put("SQL_STATEMENTS_SAVED_FOR_HISTORY", Integer.toString(iLimit)); // NOI18N + return null; } } - } catch (ClassNotFoundException ex) { - Exceptions.printStackTrace(ex); - } catch (SQLHistoryException ex) { - handleSQLHistoryException(); - } catch (NumberFormatException ne) { - inputWarningLabel.setText(NbBundle.getMessage(SQLHistoryPanel.class, "LBL_TextInputWarningLabel")); - // reset user's input - String savedLimit = NbPreferences.forModule(SQLHistoryPanel.class).get("SQL_STATEMENTS_SAVED_FOR_HISTORY", ""); // NOI18N - if (savedLimit != null) { - sqlLimitTextField.setText(savedLimit); - } else { - sqlLimitTextField.setText(SQLHistoryManager.SAVE_STATEMENTS_MAX_LIMIT_ENTERED); + + private int insertIntoDocument(String s, JEditorPane target) + throws BadLocationException { + Document doc = target.getDocument(); + if (s == null) { + s = ""; } + if (doc == null) { + return -1; } + int start = -1; + try { + Caret caret = target.getCaret(); + int p0 = Math.min(caret.getDot(), caret.getMark()); + int p1 = Math.max(caret.getDot(), caret.getMark()); + doc.remove(p0, p1 - p0); + start = caret.getDot(); + doc.insertString(start, s + ";\n", null); // NOI18N + } catch (BadLocationException ble) { + LOGGER.log(Level.WARNING, org.openide.util.NbBundle.getMessage(SQLHistoryPanel.class, "LBL_InsertAtLocationError") + ble); } - - private void handleSQLHistoryException() { - LOGGER.log(Level.WARNING, NbBundle.getMessage(SQLHistoryPanel.class, "LBL_ErrorParsingSQLHistory")); - List<SQLHistory> sqlHistoryList = SQLHistoryPersistenceManager.getInstance().retrieve(); - view.setCurrentSQLHistoryList(sqlHistoryList); - ((HistoryTableModel) sqlHistoryTable.getModel()).refreshTable(sqlHistoryList); - view.updateConnectionUrl(); + return start; } - // Variables declaration - do not modify//GEN-BEGIN:variables private javax.swing.JComboBox connectionUrlComboBox; private javax.swing.JLabel inputWarningLabel; @@ -574,200 +493,50 @@ private javax.swing.JTextField sqlLimitTextField; // End of variables declaration//GEN-END:variables - private class SQLHistoryView { - private SQLHistoryModel model; - List<SQLHistory> sqlHistoryList = new ArrayList<SQLHistory>(); - List<SQLHistory> currentSQLHistoryList = new ArrayList<SQLHistory>(); - public static final String MATCH_EMPTY = ""; // NOI18N - - public SQLHistoryView(SQLHistoryModel model) { - this.model = model; - init(); - } + private final class HistoryTableModel extends AbstractTableModel { - private void init() { - try { - this.sqlHistoryList = model.getSQLHistoryList(); - this.currentSQLHistoryList = model.getSQLHistoryList(); - } catch (SQLHistoryException ex) { - LOGGER.log(Level.INFO, NbBundle.getMessage(SQLHistoryPanel.class, "LBL_ErrorParsingSQLHistory"), ex); // NOI18N - sqlHistoryList = SQLHistoryPersistenceManager.getInstance().retrieve(); - setCurrentSQLHistoryList(sqlHistoryList); - } - } - - public void setCurrentSQLHistoryList(List<SQLHistory> sqlHistoryList) { - currentSQLHistoryList = sqlHistoryList; - } - - public List<SQLHistory> getCurrentSQLHistoryList() { - return currentSQLHistoryList; - } - - public List<SQLHistory> getSQLHistoryList() { - return sqlHistoryList; - } - - public void setSQLHistoryList(List<SQLHistory> sqlHistoryList) { - this.sqlHistoryList = sqlHistoryList; - } - - /** - * Get the SQL statement string at the row,col position in the table and convert the string to html - * @param row - table row - * @param col - table column - * @return - formatted SQL statement for the specified row, col - */ - public String getSQLHistoryTooltipValue(int row, int col) { - List<SQLHistory> sqlHistoryListForTooltip = view.getCurrentSQLHistoryList(); - if (sqlHistoryListForTooltip != null && row < sqlHistoryListForTooltip.size()) { - if (col == 0) { - String sqlRow = sqlHistoryListForTooltip.get(row).getSql().trim(); - while (sqlRow.indexOf("\n") != -1) { // NOI18N - sqlRow = replace(sqlRow, "\n", "<br>"); // NOI18N - } - return "<html>" + sqlRow + "</html>"; // NOI18N - } else { - return DateFormat.getInstance().format(sqlHistoryListForTooltip.get(row).getDate()); - } - } else { - return null; - } - } - - /** - * Convert sql statement to html for proper rendering in the table's tooltip - * @param target - original string - * @param from - string to replace - * @param to - string to replace with - * @return - updated string - */ - public String replace(String target, String from, String to) { - int start = target.indexOf(from); - if (start == -1) { - return target; - } - int lf = from.length(); - char[] targetChars = target.toCharArray(); - StringBuilder buffer = new StringBuilder(); - int copyFrom = 0; - while (start != -1) { - buffer.append(targetChars, copyFrom, start - copyFrom); - buffer.append(to); - copyFrom = start + lf; - start = target.indexOf(from, copyFrom); - } - buffer.append(targetChars, copyFrom, targetChars.length - copyFrom); - return buffer.toString(); - } + private List<SQLHistoryEntry> sqlList; + private List<String> jdbcURLs = new ArrayList<String>(); + private SQLHistoryManager shm = SQLHistoryManager.getInstance(); - public List<String> getSQLList(List<SQLHistory> sqlHistoryList) { - List<String> sqlList = new ArrayList<String>(); - if (sqlHistoryList == null) { - sqlHistoryList = getSQLHistoryList(); + public HistoryTableModel() { + refresh(); } - for (SQLHistory sqlHistory : sqlHistoryList) { - String sql = sqlHistory.getSql(); - if (!sqlList.contains(sql)) { - sqlList.add(sql); + public void refresh() { + sqlList = new ArrayList<SQLHistoryEntry>(shm.getSQLHistory()); + for (SQLHistoryEntry sqe : sqlList) { + String url = sqe.getUrl(); + if (!jdbcURLs.contains(url)) { + jdbcURLs.add(url); } } - return sqlList; + fireTableDataChanged(); } - public List<String> getDateList(List<SQLHistory> sqlHistoryList) { - List<String> dateList = new ArrayList<String>(); - List<String> sqlList = new ArrayList<String>(); - if (sqlHistoryList == null) { - sqlHistoryList = getSQLHistoryList(); - } - - for (SQLHistory sqlHistory : sqlHistoryList) { - String date = DateFormat.getInstance().format(sqlHistory.getDate()); - String sql = sqlHistory.getSql(); - // need to make sure that the date is the one that belongs with the SQL - if (!sqlList.contains(sql)) { - sqlList.add(sql); - dateList.add(date); - } - } - return dateList; - } - - public void updateConnectionUrl() { - // Initialize combo box data - currentConnections.clear(); - // Set default item in the combo box - String defaultSelectedItem = NbBundle.getMessage(SQLHistoryPanel.class, "LBL_URLComboBoxAllConnectionsItem"); - currentConnections.add(defaultSelectedItem); - - for (SQLHistory sqlHistory : sqlHistoryList) { - String url = sqlHistory.getUrl(); - if (urlAliasMap.containsKey(url)) { - // add connection display name - currentConnections.add(urlAliasMap.get(url)); - } else { - // add URL - currentConnections.add(url); - } - } - // Initialize combo box - connectionUrlComboBox.setModel(new DefaultComboBoxModel(currentConnections.toArray())); - connectionUrlComboBox.setSelectedItem(defaultSelectedItem); - connectionUrlComboBox.revalidate(); - } - - private List<SQLHistory> filterSQLHistoryList() { - List<SQLHistory> filteredSqlHistoryList = new ArrayList<SQLHistory>(); - String match = searchTextField.getText(); - String url = (String)connectionUrlComboBox.getSelectedItem(); - if (aliasUrlMap.containsKey(url)) { - url = aliasUrlMap.get(url); - } - // modify list of SQL to reflect a selection from the Connection dropdown or if a match text entered - for (SQLHistory sqlHistory : sqlHistoryList) { - if (sqlHistory.getUrl().equals(url) || url.equals(NbBundle.getMessage(SQLHistoryPanel.class, "LBL_URLComboBoxAllConnectionsItem"))) { - if (!match.equals(MATCH_EMPTY)) { - if (sqlHistory.getSql().toLowerCase().indexOf(match.toLowerCase()) != -1) { - filteredSqlHistoryList.add(sqlHistory); - } - } else { - filteredSqlHistoryList.add(sqlHistory); - } - } - } - currentSQLHistoryList = filteredSqlHistoryList; - return filteredSqlHistoryList; - } - } - - private final class HistoryTableModel extends DefaultTableModel implements ActionListener, DocumentListener { - List<String> sqlList; - List<String> dateList; - int sortCol = 1; - boolean sortAsc = false; - @Override public int getRowCount() { - if (sqlHistoryTable.getSelectedRow() == -1) { - insertSQLButton.setEnabled(false); - } - return data.length; + return sqlList.size(); } @Override public int getColumnCount() { - return 2; + return 4; } @Override public Class<?> getColumnClass(int c) { - Object value = getValueAt(0, c); - if (value == null) { + switch (c) { + case 0: return String.class; - } else { - return getValueAt(0, c).getClass(); + case 1: + return String.class; + case 2: + return Date.class; + case 3: + return SQLHistoryEntry.class; + default: + return Object.class; } } @@ -778,350 +547,59 @@ @Override public Object getValueAt(int row, int col) { - if (sqlHistoryTable.isRowSelected(row)) { - insertSQLButton.setEnabled(true); + switch (col) { + case 0: + return sqlList.get(row).getUrl(); + case 1: + return sqlList.get(row).getSql(); + case 2: + return sqlList.get(row).getDate(); + case 3: + return sqlList.get(row); + default: + return null; } - return data[row][col]; } @Override public void setValueAt(Object value, int row, int col) { - adjustColumnPreferredWidths(sqlHistoryTable); - fireTableCellUpdated(row, col); + throw new NotImplementedException(); + } + + public List<String> getJdbcURLs() { + return jdbcURLs; + } + } + + private class EqualsFilter extends RowFilter<HistoryTableModel, Integer> { + + private String referenz; + private int referenzColumn; + + public EqualsFilter(String referenz, int referenzColumn) { + this.referenz = referenz; + this.referenzColumn = referenzColumn; + } + + @Override + public boolean include(Entry<? extends HistoryTableModel, ? extends Integer> entry) { + return ((String) entry.getModel().getValueAt(entry.getIdentifier(), referenzColumn)).equals(referenz); + } + }; + + private class ContainsInsensitiveFilter extends RowFilter<HistoryTableModel, Integer> { + + private String referenz; + private int referenzColumn; + + public ContainsInsensitiveFilter(String referenz, int referenzColumn) { + this.referenz = referenz.toLowerCase(); + this.referenzColumn = referenzColumn; } @Override - public void addTableModelListener(TableModelListener arg0) { - // not used - } - - @Override - public void removeTableModelListener(TableModelListener arg0) { - // not used - } - - public void adjustColumnPreferredWidths(JTable table) { - // Get max width for cells in column and make that the preferred width - TableColumnModel columnModel = table.getColumnModel(); - for (int col = 0; col < table.getColumnCount(); col++) { - - int maxwidth = 0; - for (int row = 0; row < table.getRowCount(); row++) { - TableCellRenderer rend = - table.getCellRenderer(row, col); - Object value = table.getValueAt(row, col); - Component comp = - rend.getTableCellRendererComponent(table, - value, - false, - false, - row, - col); - maxwidth = Math.max(comp.getPreferredSize().width, maxwidth); - } - TableColumn column = columnModel.getColumn(col); - column.setPreferredWidth(maxwidth); - column.setHeaderRenderer(createDefaultRenderer()); - } - } - - @Override - public void actionPerformed(ActionEvent evt) { - processUpdate(); - } - - public void refreshTable(List<SQLHistory> sqlHistoryList) { - if (initTask == null) { - return ; - } - String url; - // Get the connection url from the combo box - if (sqlHistoryList.size() > 0) { - url = connectionUrlComboBox.getSelectedItem().toString(); - if (aliasUrlMap.containsKey(url)) { - url = aliasUrlMap.get(url); - } - } else { - url = NbBundle.getMessage(SQLHistoryPanel.class, "LBL_URLComboBoxAllConnectionsItem"); - } - sqlList = new ArrayList<String>(); - dateList = new ArrayList<String>(); - connectionUrlComboBox.setToolTipText(url); - int length; - int maxLength; - for (SQLHistory sqlHistory : sqlHistoryList) { - if (url.equals(NbBundle.getMessage(SQLHistoryPanel.class, "LBL_URLComboBoxAllConnectionsItem")) || - url.equals(sqlHistory.getUrl())) { - length = sqlHistory.getSql().trim().length(); - maxLength = length > TABLE_DATA_WIDTH_SQL ? TABLE_DATA_WIDTH_SQL : length; - sqlList.add(sqlHistory.getSql().trim().substring(0, maxLength).replaceAll("\n", " ")); - dateList.add(DateFormat.getInstance().format(sqlHistory.getDate())); - } - } - // Initialize sql column data - data = null; - data = new Object[sqlList.size()][2]; - int row = 0; - for (String sql : sqlList) { - length = sql.trim().length(); - maxLength = length > TABLE_DATA_WIDTH_SQL ? TABLE_DATA_WIDTH_SQL : length; - data[row][0] = sql.trim().substring(0, maxLength).replaceAll("\n", " "); - row++; - } - // Initialize date column data - row = 0; - for (String date : dateList) { - data[row++][1] = date; - } - // Refresh table - if (data.length > 0) { - sqlHistoryTable.revalidate(); - } else { - sqlHistoryTable.revalidate(); - insertSQLButton.setEnabled(false); - } - } - - @Override - public void insertUpdate(DocumentEvent evt) { - processUpdate(); - } - - @Override - public void removeUpdate(DocumentEvent evt) { - processUpdate(); - } - - private void processUpdate() { - view.setCurrentSQLHistoryList(view.filterSQLHistoryList()); - sqlHistoryTable.repaint(); - sqlHistoryTable.clearSelection(); - refreshTable(view.getCurrentSQLHistoryList()); - } - - @Override - public void changedUpdate(DocumentEvent arg0) { - // unused - } - - public List<SQLHistory> sortData() { - // Refresh the table - List<SQLHistory> filteredSQLHistoryList = view.filterSQLHistoryList(); - SQLComparator sqlComparator = new SQLComparator(sortCol, sortAsc); - Collections.sort(filteredSQLHistoryList, sqlComparator); - view.setCurrentSQLHistoryList(filteredSQLHistoryList); - refreshTable( filteredSQLHistoryList); - return filteredSQLHistoryList; - } + public boolean include(Entry<? extends HistoryTableModel, ? extends Integer> entry) { + return ((String) entry.getModel().getValueAt(entry.getIdentifier(), referenzColumn)).toLowerCase().contains(referenz); } - - public static String read(Document doc) throws InterruptedException, Exception { - Renderer r = new Renderer(doc); - doc.render(r); - - synchronized (r) { - while (!r.done) { - r.wait(); - if (r.err != null) { - throw new Exception(r.err); - } - } - } - return r.result; - } - - private static class Renderer implements Runnable { - Document doc; - String result; - Throwable err; - boolean done; - - Renderer(Document doc) { - this.doc = doc; - } - - @Override - public synchronized void run() { - try { - result = doc.getText(0, doc.getLength()); - } catch (Throwable e) { - err = e; - Exceptions.printStackTrace(e); - } - done = true; - notify(); - } - } - - private class InsertSQLUtility { - - public InsertSQLUtility() { - } - - public void insert(String s, JEditorPane target) - throws BadLocationException { - insert(s, target, false); - } - - public void insert(String s, JEditorPane target, boolean reformat) - throws BadLocationException { - - if (s == null) { - s = ""; // NOI18N - } - - Document doc = target.getDocument(); - if (doc != null) { - insert(s, target, doc); - } - } - - private int insert(String s, JEditorPane target, Document doc) - throws BadLocationException { - - int start = -1; - try { - Caret caret = target.getCaret(); - int p0 = Math.min(caret.getDot(), caret.getMark()); - int p1 = Math.max(caret.getDot(), caret.getMark()); - doc.remove(p0, p1 - p0); - start = caret.getDot(); - doc.insertString(start, s + ";\n", null); // NOI18N - } catch (BadLocationException ble) { - LOGGER.log(Level.WARNING, org.openide.util.NbBundle.getMessage(SQLHistoryPanel.class, "LBL_InsertAtLocationError") + ble); - } - return start; - } - } - - private static void adjustColumnPreferredWidths(JTable table) { - TableColumnModel columnModel = table.getColumnModel(); - for (int col = 0; col < table.getColumnCount(); col++) { - - int maxwidth = 0; - for (int row = 0; row < table.getRowCount(); row++) { - TableCellRenderer rend = - table.getCellRenderer(row, col); - Object value = table.getValueAt(row, col); - Component comp = - rend.getTableCellRendererComponent(table, - value, - false, - false, - row, - col); - maxwidth = Math.max(comp.getPreferredSize().width, maxwidth); - } - TableColumn column = columnModel.getColumn(col); - column.setPreferredWidth(maxwidth); - } - } - - private static final class ConnectionUrlRenderer extends DefaultListCellRenderer { - - @Override - public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) { - JLabel component = (JLabel) super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus); - component.setToolTipText((String) value); - return component; - } - } - - private TableCellRenderer createDefaultRenderer() { - DefaultTableCellRenderer label = new DefaultTableCellRenderer() { - - @Override - public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) { - if (table != null) { - JTableHeader header = table.getTableHeader(); - if (header != null) { - setForeground(header.getForeground()); - setBackground(header.getBackground()); - setFont(header.getFont()); - } - } - setText((value == null) ? "" : value.toString()); - setBorder(UIManager.getBorder("TableHeader.cellBorder")); - return SQLHistoryPanel.this; - } - }; - label.setHorizontalAlignment(JLabel.CENTER); - return label; - } - - private class ColumnListener extends MouseAdapter { - @Override - public void mouseClicked(MouseEvent e) { - HistoryTableModel model = (HistoryTableModel)sqlHistoryTable.getModel(); - TableColumnModel colModel = sqlHistoryTable.getColumnModel(); - int colModelIndex = colModel.getColumnIndexAtX(e.getX()); - int modelIndex = colModel.getColumn(colModelIndex).getModelIndex(); - if (modelIndex < 0) { - return; - } - if (model.sortCol == modelIndex) { - model.sortAsc = !model.sortAsc; - } else { - model.sortCol = modelIndex; - } - model.sortData(); - sqlHistoryTable.tableChanged(new TableModelEvent(model)); - sqlHistoryTable.repaint(); - } - } - - private class SQLComparator implements Comparator<SQLHistory> { - - protected int sortCol; - protected boolean sortAsc; - - public SQLComparator(int sortCol, boolean sortAsc) { - this.sortCol = sortCol; - this.sortAsc = sortAsc; - } - - @Override - public int compare(SQLHistory sql1, SQLHistory sql2) { - int result = 0; - if (!(sql1 instanceof SQLHistory) || !(sql2 instanceof SQLHistory)) { - return result; - } - SQLHistory sqlHistory1 = sql1; - SQLHistory sqlHistory2 = sql2; - - switch (sortCol) { - case 0: // SQL - String s1 = sqlHistory1.getSql().trim().toLowerCase(); - String s2 = sqlHistory2.getSql().trim().toLowerCase(); - result = s1.compareTo(s2); - break; - case 1: // Date - Date d1 = sqlHistory1.getDate(); - Date d2 = sqlHistory2.getDate(); - result = d1.compareTo(d2); - break; - } - if (!sortAsc) { - result = -result; - } - return result; - } - - @Override - public boolean equals(Object obj) { - if (obj instanceof SQLComparator) { - SQLComparator compObj = (SQLComparator) obj; - return (compObj.sortCol == sortCol) && (compObj.sortAsc == sortAsc); - } - return false; - } - - @Override - public int hashCode() { - int hash = 3; - hash = 17 * hash + this.sortCol; - hash = 17 * hash + (this.sortAsc ? 1 : 0); - return hash; - } - } + }; } diff --git a/db.core/src/org/netbeans/modules/db/sql/history/SQLHistory.java b/db.core/src/org/netbeans/modules/db/sql/history/SQLHistory.java --- a/db.core/src/org/netbeans/modules/db/sql/history/SQLHistory.java +++ b/db.core/src/org/netbeans/modules/db/sql/history/SQLHistory.java @@ -1,74 +1,124 @@ -/* - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. - * - * Copyright 2008-2010 Oracle and/or its affiliates. All rights reserved. - * - * Oracle and Java are registered trademarks of Oracle and/or its affiliates. - * Other names may be trademarks of their respective owners. - * - * The contents of this file are subject to the terms of either the GNU - * General Public License Version 2 only ("GPL") or the Common - * Development and Distribution License("CDDL") (collectively, the - * "License"). You may not use this file except in compliance with the - * License. You can obtain a copy of the License at - * http://www.netbeans.org/cddl-gplv2.html - * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the - * specific language governing permissions and limitations under the - * License. When distributing the software, include this License Header - * Notice in each file and include the License file at - * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the GPL Version 2 section of the License file that - * accompanied this code. If applicable, add the following below the - * License Header, with the fields enclosed by brackets [] replaced by - * your own identifying information: - * "Portions Copyrighted [year] [name of copyright owner]" - * - * If you wish your version of this file to be governed by only the CDDL - * or only the GPL Version 2, indicate your decision by adding - * "[Contributor] elects to include this software in this distribution - * under the [CDDL or GPL Version 2] license." If you do not indicate a - * single choice of license, a recipient has the option to distribute - * your version of this file under either the CDDL, the GPL Version 2 or - * to extend the choice of license to its licensees as provided above. - * However, if you add GPL Version 2 code and therefore, elected the GPL - * Version 2 license, then the option applies only if the new code is - * made subject to such option by the copyright holder. - * - * Contributor(s): - * - * Portions Copyrighted 2008-2010 Sun Microsystems, Inc. - */ package org.netbeans.modules.db.sql.history; -import java.util.Date; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.Comparator; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.Set; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlRootElement; +import javax.xml.bind.annotation.XmlTransient; -/** - * - * @author John Baker - */ -public class SQLHistory { - String sql; - String url; - Date date; +@XmlRootElement(name="history") +public class SQLHistory implements Set<SQLHistoryEntry> { + @XmlTransient + private int historyLimit = 100; + @XmlElement(name="sql") + private Set<SQLHistoryEntry> history; + + public SQLHistory() { + history = new HashSet<SQLHistoryEntry>(); + } + + public String toString() { + return history.toString(); + } + + public <T> T[] toArray(T[] a) { + return history.toArray(a); + } + + public Object[] toArray() { + return history.toArray(); + } + + public int size() { + return history.size(); + } + + public boolean retainAll(Collection<?> c) { + return history.retainAll(c); + } + + public boolean removeAll(Collection<?> c) { + return history.removeAll(c); + } + + public boolean remove(Object o) { + return history.remove(o); + } + + public Iterator<SQLHistoryEntry> iterator() { + return history.iterator(); + } - public SQLHistory(String url, String sql, Date date) { - this.url = url; - this.sql = sql; - this.date = date; + public boolean isEmpty() { + return history.isEmpty(); } - public String getUrl() { - return url; + public int hashCode() { + return history.hashCode(); } - public String getSql() { - return sql; + public boolean equals(Object o) { + return history.equals(o); } - public Date getDate() { - return date; + public boolean containsAll(Collection<?> c) { + return history.containsAll(c); } + public boolean contains(Object o) { + return history.contains(o); + } + + public void clear() { + history.clear(); + } + + public boolean addAll(Collection<? extends SQLHistoryEntry> c) { + boolean changed = false; + for(SQLHistoryEntry sqe: c) { + changed |= this.add(sqe); + } + return changed; + } + + public boolean add(SQLHistoryEntry e) { + boolean result = history.add(e); + if(! result) { + history.remove(e); + result = history.add(e); + } + enforceLimit(); + return result; + } + + public void enforceLimit() { + if(size() > historyLimit) { + List<SQLHistoryEntry> list = new ArrayList<SQLHistoryEntry>(history); + Collections.sort(list, new Comparator<SQLHistoryEntry>() { + @Override + public int compare(SQLHistoryEntry o1, SQLHistoryEntry o2) { + return o2.getDate().compareTo(o1.getDate()); + } + }); + history.clear(); + history.addAll(list.subList(0, historyLimit)); + } + } + + @XmlTransient + public int getHistoryLimit() { + return historyLimit; + } + + public void setHistoryLimit(int historyLimit) { + this.historyLimit = historyLimit; + enforceLimit(); + } } diff --git a/db.core/src/org/netbeans/modules/db/sql/history/SQLHistoryEntry.java b/db.core/src/org/netbeans/modules/db/sql/history/SQLHistoryEntry.java new file mode 100644 --- /dev/null +++ b/db.core/src/org/netbeans/modules/db/sql/history/SQLHistoryEntry.java @@ -0,0 +1,152 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright 2011 Oracle and/or its affiliates. All rights reserved. + * + * Oracle and Java are registered trademarks of Oracle and/or its affiliates. + * Other names may be trademarks of their respective owners. + * + * The contents of this file are subject to the terms of either the GNU + * General Public License Version 2 only ("GPL") or the Common + * Development and Distribution License("CDDL") (collectively, the + * "License"). You may not use this file except in compliance with the + * License. You can obtain a copy of the License at + * http://www.netbeans.org/cddl-gplv2.html + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the + * specific language governing permissions and limitations under the + * License. When distributing the software, include this License Header + * Notice in each file and include the License file at + * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the GPL Version 2 section of the License file that + * accompanied this code. If applicable, add the following below the + * License Header, with the fields enclosed by brackets [] replaced by + * your own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * If you wish your version of this file to be governed by only the CDDL + * or only the GPL Version 2, indicate your decision by adding + * "[Contributor] elects to include this software in this distribution + * under the [CDDL or GPL Version 2] license." If you do not indicate a + * single choice of license, a recipient has the option to distribute + * your version of this file under either the CDDL, the GPL Version 2 or + * to extend the choice of license to its licensees as provided above. + * However, if you add GPL Version 2 code and therefore, elected the GPL + * Version 2 license, then the option applies only if the new code is + * made subject to such option by the copyright holder. + * + * Contributor(s): + * + * Portions Copyrighted 2011 Sun Microsystems, Inc. + */ +package org.netbeans.modules.db.sql.history; + +import java.text.DateFormat; +import java.text.ParseException; +import java.util.Date; +import javax.xml.bind.annotation.XmlAttribute; +import javax.xml.bind.annotation.XmlTransient; +import javax.xml.bind.annotation.XmlType; +import javax.xml.bind.annotation.XmlValue; + +@XmlType(name = "sql") +public class SQLHistoryEntry { + + private String url; + private String sql; + private Date date; + + protected SQLHistoryEntry() { + } + + public SQLHistoryEntry(String url, String sql, Date date) { + this.url = url; + this.sql = sql; + this.date = date; + } + + @XmlTransient + public Date getDate() { + return date; + } + + protected void setDate(Date date) { + this.date = date; + } + + @XmlValue + public String getSql() { + return sql; + } + + protected void setSql(String sql) { + if (sql != null) { + this.sql = sql.trim(); + } else { + this.sql = sql; + } + } + + @XmlAttribute + public String getUrl() { + return url; + } + + protected void setUrl(String url) { + this.url = url; + } + + @XmlAttribute(name = "date") + protected String getDateXMLVariant() { + if (this.date == null) { + return null; + } else { + return Long.toString(date.getTime()); + } + } + + protected void setDateXMLVariant(String value) { + try { + date = new Date(Long.parseLong(value)); + } catch (NumberFormatException nfe) { + // #152486 - previously date stored in text format + try { + date = DateFormat.getDateTimeInstance(DateFormat.SHORT, DateFormat.SHORT).parse(value); + } catch (ParseException pe) { + // # 152486; Date stored is not parsable, so reset the date to the current timestamp + date = new Date(); + } + } + + } + + @Override + public String toString() { + return "SQLHistoryEntry{" + "url=" + url + ", sql=" + sql + ", date=" + date + '}'; + } + + @Override + public boolean equals(Object obj) { + if (obj == null) { + return false; + } + if (getClass() != obj.getClass()) { + return false; + } + final SQLHistoryEntry other = (SQLHistoryEntry) obj; + if ((this.url == null) ? (other.url != null) : !this.url.toLowerCase().equals(other.url.toLowerCase())) { + return false; + } + if ((this.sql == null) ? (other.sql != null) : !this.sql.toLowerCase().equals(other.sql.toLowerCase())) { + return false; + } + return true; + } + + @Override + public int hashCode() { + int hash = 7; + hash = 37 * hash + (this.sql != null ? this.sql.toLowerCase().hashCode() : 0); + return hash; + } +} diff --git a/db.core/src/org/netbeans/modules/db/sql/history/SQLHistoryException.java b/db.core/src/org/netbeans/modules/db/sql/history/SQLHistoryException.java deleted file mode 100644 --- a/db.core/src/org/netbeans/modules/db/sql/history/SQLHistoryException.java +++ /dev/null @@ -1,58 +0,0 @@ -/* - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. - * - * Copyright 2010 Oracle and/or its affiliates. All rights reserved. - * - * Oracle and Java are registered trademarks of Oracle and/or its affiliates. - * Other names may be trademarks of their respective owners. - * - * The contents of this file are subject to the terms of either the GNU - * General Public License Version 2 only ("GPL") or the Common - * Development and Distribution License("CDDL") (collectively, the - * "License"). You may not use this file except in compliance with the - * License. You can obtain a copy of the License at - * http://www.netbeans.org/cddl-gplv2.html - * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the - * specific language governing permissions and limitations under the - * License. When distributing the software, include this License Header - * Notice in each file and include the License file at - * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the GPL Version 2 section of the License file that - * accompanied this code. If applicable, add the following below the - * License Header, with the fields enclosed by brackets [] replaced by - * your own identifying information: - * "Portions Copyrighted [year] [name of copyright owner]" - * - * If you wish your version of this file to be governed by only the CDDL - * or only the GPL Version 2, indicate your decision by adding - * "[Contributor] elects to include this software in this distribution - * under the [CDDL or GPL Version 2] license." If you do not indicate a - * single choice of license, a recipient has the option to distribute - * your version of this file under either the CDDL, the GPL Version 2 or - * to extend the choice of license to its licensees as provided above. - * However, if you add GPL Version 2 code and therefore, elected the GPL - * Version 2 license, then the option applies only if the new code is - * made subject to such option by the copyright holder. - * - * Contributor(s): - * - * Portions Copyrighted 2008 Sun Microsystems, Inc. - */ - -package org.netbeans.modules.db.sql.history; - -/** - * - * @author jbaker - */ -public class SQLHistoryException extends Exception { - SQLHistoryException() { - } - - SQLHistoryException(String msg) { - } - - SQLHistoryException(String msg, Throwable cause) { - } -} diff --git a/db.core/src/org/netbeans/modules/db/sql/history/SQLHistoryManager.java b/db.core/src/org/netbeans/modules/db/sql/history/SQLHistoryManager.java --- a/db.core/src/org/netbeans/modules/db/sql/history/SQLHistoryManager.java +++ b/db.core/src/org/netbeans/modules/db/sql/history/SQLHistoryManager.java @@ -41,31 +41,48 @@ */ package org.netbeans.modules.db.sql.history; - -import java.util.ArrayList; -import java.util.List; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; import java.util.logging.Level; import java.util.logging.Logger; +import javax.xml.bind.JAXBContext; +import javax.xml.bind.JAXBException; +import javax.xml.bind.Marshaller; +import javax.xml.bind.Unmarshaller; import org.netbeans.modules.db.sql.execute.ui.SQLHistoryPanel; import org.openide.filesystems.FileObject; import org.openide.filesystems.FileUtil; -import org.openide.util.NbBundle; +import org.openide.util.Exceptions; +import org.openide.util.NbPreferences; /** * * @author John Baker */ public class SQLHistoryManager { - public static final String SQL_HISTORY_FOLDER = "Databases/SQLHISTORY"; // NOI18N - public static final String SQL_HISTORY_FILE_NAME = "sql_history.xml"; // NOI18N - public static final String SAVE_STATEMENTS_MAX_LIMIT_ENTERED = "100"; // NOI18N + + JAXBContext context; + private static final String SQL_HISTORY_DIRECTORY = "Databases/SQLHISTORY"; // NOI18N + private static final String SQL_HISTORY_FILE = "sql_history.xml"; // NOI18N + public static final String OPT_SQL_STATEMENTS_SAVED_FOR_HISTORY = "SQL_STATEMENTS_SAVED_FOR_HISTORY"; // NOI18N + public static final int DEFAULT_SQL_STATEMENTS_SAVED_FOR_HISTORY = 100; + public static final int MAX_SQL_STATEMENTS_SAVED_FOR_HISTORY = 10000; private static SQLHistoryManager _instance = null; - private static final Logger LOGGER = Logger.getLogger(SQLHistory.class.getName()); - private List<SQLHistory> sqlList = new ArrayList<SQLHistory>(); - private int listSize; - private FileObject historyRoot; + private static final Logger LOGGER = Logger.getLogger(SQLHistoryEntry.class.getName()); + private SQLHistory sqlHistory; - private SQLHistoryManager() { + protected SQLHistoryManager() { + ClassLoader orig = Thread.currentThread().getContextClassLoader(); + Thread.currentThread().setContextClassLoader(SQLHistoryManager.class.getClassLoader()); + try { + context = JAXBContext.newInstance("org.netbeans.modules.db.sql.history", SQLHistoryManager.class.getClassLoader()); + loadHistory(); + } catch (JAXBException ex) { + throw new RuntimeException(ex); + } finally { + Thread.currentThread().setContextClassLoader(orig); + } } public static SQLHistoryManager getInstance() { @@ -75,107 +92,76 @@ return _instance; } - /** - * Get the value of listSize - * - * @return the value of listSize - */ public int getListSize() { - return listSize; + return NbPreferences.forModule(SQLHistoryPanel.class).getInt("OPT_SQL_STATEMENTS_SAVED_FOR_HISTORY", DEFAULT_SQL_STATEMENTS_SAVED_FOR_HISTORY); + } + + protected FileObject getHistoryRoot(boolean create) throws IOException { + FileObject result = null; + FileObject historyRootDir = getConfigRoot().getFileObject(getRelativeHistoryPath()); + if (historyRootDir != null || create) { + if (historyRootDir == null) { + historyRootDir = FileUtil.createFolder(getConfigRoot(), getRelativeHistoryPath()); + } + FileObject historyRoot = historyRootDir.getFileObject(getHistoryFilename()); + + if (historyRoot != null || create) { + if(historyRoot == null) { + historyRoot = historyRootDir.createData(getHistoryFilename()); + } + result = historyRoot; + } + } + return result; } - public FileObject getHistoryRoot() { - return historyRoot; + protected FileObject getConfigRoot() { + return FileUtil.getConfigRoot(); + } + + protected String getRelativeHistoryPath() { + return SQL_HISTORY_DIRECTORY; } - public void setHistoryRoot(FileObject root) { - historyRoot = root; + protected String getHistoryFilename() { + return SQL_HISTORY_FILE; + } + + public void setListSize(int listSize) { + NbPreferences.forModule(SQLHistoryPanel.class).putInt("OPT_SQL_STATEMENTS_SAVED_FOR_HISTORY", listSize); + sqlHistory.setHistoryLimit(listSize); } - /** - * Set the value of listSize - * - * @param listSize new value of listSize - */ - public void setListSize(int listSize) { - this.listSize = listSize; - } + public void saveSQL(SQLHistoryEntry sqlStored) { + sqlHistory.add(sqlStored); + } - - public void saveSQL(SQLHistory sqlStored) { - sqlList.add(sqlStored); - } - - public void save(FileObject userdirRoot) { + private void loadHistory() { try { - // create a folder in the userdir for sql_history.xml file that maintains a list of executed SQL - setHistoryRoot(userdirRoot.getFileObject(SQL_HISTORY_FOLDER)); - if (null == historyRoot || !historyRoot.isValid()) { - historyRoot = FileUtil.createFolder(userdirRoot, SQL_HISTORY_FOLDER); - } - // Start managing the persistence of SQL statements that have been executed - SQLHistoryPersistenceManager.getInstance().create(historyRoot, sqlList); - sqlList.clear(); + Unmarshaller unmarshaller = context.createUnmarshaller(); + InputStream is = getHistoryRoot(false).getInputStream(); + sqlHistory = (SQLHistory) unmarshaller.unmarshal(is); + sqlHistory.setHistoryLimit(getListSize()); + is.close(); } catch (Exception ex) { + sqlHistory = new SQLHistory(); + sqlHistory.setHistoryLimit(getListSize()); LOGGER.log(Level.INFO, ex.getMessage()); - LOGGER.log(Level.INFO, NbBundle.getMessage(SQLHistoryManager.class, "MSG_ErrorParsingHistoryFile")); } } - public List<SQLHistory> getSQLHistory() { - return sqlList; - } - - public List<SQLHistory> retrieve() { - return new ArrayList<SQLHistory>(); - - } + public void save() { + try { + Marshaller marshaller = context.createMarshaller(); + OutputStream os = getHistoryRoot(true).getOutputStream(); + marshaller.marshal(sqlHistory, os); + os.close(); + } catch (Exception ex) { + LOGGER.log(Level.INFO, ex.getMessage()); + } + } - public List<String> retrieve(String url) { - List<String> sqlAsString = new ArrayList<String>(); - String sql; - if (!getUrlsUsed().isEmpty()) { - for (SQLHistory historyItem : sqlList) { - sql = historyItem.getSql(); - if (url.equals(historyItem.getUrl())) { - sqlAsString.add(sql); - } - } - } - return sqlAsString; - - } - - private List<String> getUrlsUsed() { - List<String> urls = new ArrayList<String>(); - String url; - for (SQLHistory historyItem : sqlList) { - url = historyItem.getUrl(); - if (!urls.contains(url)) { - urls.add(url); - } - } - return urls; - } - - public int updateList(int limit, String historyFilePath, FileObject root) throws SQLHistoryException { - List<SQLHistory> updatedSQLHistoryList = new ArrayList<SQLHistory>(); - int numItemsToRemove = 0; - try { - updatedSQLHistoryList = SQLHistoryPersistenceManager.getInstance().retrieve(root); - if (limit >= updatedSQLHistoryList.size()) { - // no changes needed to the current list - return -1; - } - // Remove elements from list based on the number of statements to save that is set in the SQL History dialog - numItemsToRemove = updatedSQLHistoryList.size() - limit; - for (int i = 0; i < numItemsToRemove; i++) { - updatedSQLHistoryList.remove(0); - } - } catch (ClassNotFoundException ex) { - LOGGER.log(Level.INFO, NbBundle.getMessage(SQLHistoryPanel.class, "MSG_RuntimeErrorRetrievingHistory") + ex); - } - sqlList = updatedSQLHistoryList; - return numItemsToRemove; + public SQLHistory getSQLHistory() { + return sqlHistory; } } diff --git a/db.core/src/org/netbeans/modules/db/sql/history/SQLHistoryModel.java b/db.core/src/org/netbeans/modules/db/sql/history/SQLHistoryModel.java deleted file mode 100644 --- a/db.core/src/org/netbeans/modules/db/sql/history/SQLHistoryModel.java +++ /dev/null @@ -1,62 +0,0 @@ -/* - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. - * - * Copyright 2010 Oracle and/or its affiliates. All rights reserved. - * - * Oracle and Java are registered trademarks of Oracle and/or its affiliates. - * Other names may be trademarks of their respective owners. - * - * The contents of this file are subject to the terms of either the GNU - * General Public License Version 2 only ("GPL") or the Common - * Development and Distribution License("CDDL") (collectively, the - * "License"). You may not use this file except in compliance with the - * License. You can obtain a copy of the License at - * http://www.netbeans.org/cddl-gplv2.html - * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the - * specific language governing permissions and limitations under the - * License. When distributing the software, include this License Header - * Notice in each file and include the License file at - * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the GPL Version 2 section of the License file that - * accompanied this code. If applicable, add the following below the - * License Header, with the fields enclosed by brackets [] replaced by - * your own identifying information: - * "Portions Copyrighted [year] [name of copyright owner]" - * - * If you wish your version of this file to be governed by only the CDDL - * or only the GPL Version 2, indicate your decision by adding - * "[Contributor] elects to include this software in this distribution - * under the [CDDL or GPL Version 2] license." If you do not indicate a - * single choice of license, a recipient has the option to distribute - * your version of this file under either the CDDL, the GPL Version 2 or - * to extend the choice of license to its licensees as provided above. - * However, if you add GPL Version 2 code and therefore, elected the GPL - * Version 2 license, then the option applies only if the new code is - * made subject to such option by the copyright holder. - * - * Contributor(s): - * - * Portions Copyrighted 2008 Sun Microsystems, Inc. - */ - -package org.netbeans.modules.db.sql.history; - -import java.util.List; - -/** - * - * @author John Baker - */ -public interface SQLHistoryModel { - void initialize(); - - void setFilter(String filter); - - String getFilter(); - - List<SQLHistory> getSQLHistoryList() throws SQLHistoryException; - - void setSQLHistoryList(List<SQLHistory> sqlHistoryList); - -} diff --git a/db.core/src/org/netbeans/modules/db/sql/history/SQLHistoryModelImpl.java b/db.core/src/org/netbeans/modules/db/sql/history/SQLHistoryModelImpl.java deleted file mode 100644 --- a/db.core/src/org/netbeans/modules/db/sql/history/SQLHistoryModelImpl.java +++ /dev/null @@ -1,177 +0,0 @@ -/* - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. - * - * Copyright 2010 Oracle and/or its affiliates. All rights reserved. - * - * Oracle and Java are registered trademarks of Oracle and/or its affiliates. - * Other names may be trademarks of their respective owners. - * - * The contents of this file are subject to the terms of either the GNU - * General Public License Version 2 only ("GPL") or the Common - * Development and Distribution License("CDDL") (collectively, the - * "License"). You may not use this file except in compliance with the - * License. You can obtain a copy of the License at - * http://www.netbeans.org/cddl-gplv2.html - * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the - * specific language governing permissions and limitations under the - * License. When distributing the software, include this License Header - * Notice in each file and include the License file at - * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the GPL Version 2 section of the License file that - * accompanied this code. If applicable, add the following below the - * License Header, with the fields enclosed by brackets [] replaced by - * your own identifying information: - * "Portions Copyrighted [year] [name of copyright owner]" - * - * If you wish your version of this file to be governed by only the CDDL - * or only the GPL Version 2, indicate your decision by adding - * "[Contributor] elects to include this software in this distribution - * under the [CDDL or GPL Version 2] license." If you do not indicate a - * single choice of license, a recipient has the option to distribute - * your version of this file under either the CDDL, the GPL Version 2 or - * to extend the choice of license to its licensees as provided above. - * However, if you add GPL Version 2 code and therefore, elected the GPL - * Version 2 license, then the option applies only if the new code is - * made subject to such option by the copyright holder. - * - * Contributor(s): - * - * Portions Copyrighted 2010 Sun Microsystems, Inc. - */ - -package org.netbeans.modules.db.sql.history; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; -import java.util.logging.Logger; -import org.openide.filesystems.FileObject; -import org.openide.filesystems.FileUtil; -import org.openide.util.NbPreferences; - -/** - * - * @author John Baker - */ -public class SQLHistoryModelImpl implements SQLHistoryModel { - private static final int SAVE_STATEMENTS_EMPTY = 0; // NOI18N - private static final String SAVE_STATEMENTS_CLEARED = ""; // NOI18N - private static final Logger LOGGER = Logger.getLogger(SQLHistoryModelImpl.class.getName()); - private static final FileObject USERDIR = FileUtil.getConfigRoot(); - - List<SQLHistory> _sqlHistoryList = new ArrayList<SQLHistory>(); - - @Override - public void initialize() { - throw new UnsupportedOperationException("Not supported yet."); - } - - @Override - public void setFilter(String filter) { - throw new UnsupportedOperationException("Not supported yet."); - } - - @Override - public String getFilter() { - throw new UnsupportedOperationException("Not supported yet."); - } - - @Override - public List<SQLHistory> getSQLHistoryList() throws SQLHistoryException { - List<SQLHistory> retrievedSQL = new ArrayList<SQLHistory>(); - _sqlHistoryList.clear(); - try { - boolean isRewriteSQLRequired = false; - FileObject historyRoot = USERDIR.getFileObject(SQLHistoryManager.SQL_HISTORY_FOLDER); - if (historyRoot == null) { - return new ArrayList<SQLHistory>(); - } - // Read persisted SQL from file - retrievedSQL = SQLHistoryPersistenceManager.getInstance().retrieve(historyRoot); - // Remove duplicates - if (!isSQLUnique(retrievedSQL)) { - retrievedSQL = removeDuplicates(retrievedSQL); - isRewriteSQLRequired = true; - } - // Get saved limit - String savedLimit = NbPreferences.forModule(SQLHistoryPersistenceManager.class).get("SQL_STATEMENTS_SAVED_FOR_HISTORY", ""); - if (savedLimit.equals(SAVE_STATEMENTS_CLEARED)) { - savedLimit = SQLHistoryManager.SAVE_STATEMENTS_MAX_LIMIT_ENTERED; - } - int limit = Integer.parseInt(savedLimit); - // Remove any elements if save limit is exceeded - if (retrievedSQL.size() > limit) { - retrievedSQL = removeExtraSQL(retrievedSQL, limit); - isRewriteSQLRequired = true; - } - if (isRewriteSQLRequired) { - // Remove all elements from sql_history.xml - SQLHistoryPersistenceManager.getInstance().updateSQLSaved(SAVE_STATEMENTS_EMPTY, historyRoot); - // Write new list; reversing list is required for persisting the SQL - Collections.reverse(retrievedSQL); - SQLHistoryPersistenceManager.getInstance().create(historyRoot, retrievedSQL); - // return list to the expected order for viewing - Collections.reverse(retrievedSQL); - } - } catch (ClassNotFoundException ex) { - throw new SQLHistoryException(); - } - return retrievedSQL; - } - - private boolean isSQLUnique(List<SQLHistory> sqlHistoryList) { - List<SQLHistory> revSqLHistoryList = new ArrayList<SQLHistory>(); - boolean isUnique = true; - - for (SQLHistory sqlHistory : sqlHistoryList) { - for (SQLHistory revHistory : revSqLHistoryList) { - if (revHistory.getSql().trim().equals(sqlHistory.getSql().trim())) { - if (revHistory.getUrl().equals(sqlHistory.getUrl())) { - isUnique = false; - } - } - } - revSqLHistoryList.add(sqlHistory); - } - return isUnique; - } - - private List<SQLHistory> removeDuplicates(List<SQLHistory> sqlHistoryList) { - List<SQLHistory> revSqLHistoryList = new ArrayList<SQLHistory>(); - boolean canAdd = true; - for (SQLHistory sqlHistory : sqlHistoryList) { - for (SQLHistory revHistory : revSqLHistoryList) { - if (revHistory.getSql().trim().equals(sqlHistory.getSql().trim())) { - if (revHistory.getUrl().equals(sqlHistory.getUrl())) { - canAdd = false; - } - } - } - if (canAdd) { - revSqLHistoryList.add(sqlHistory); - } else { - canAdd = true; - } - } - return revSqLHistoryList; - } - - private List<SQLHistory> removeExtraSQL(List<SQLHistory> sqlHistoryList, int limit) { - int i = 0; - List<SQLHistory> revSqLHistoryList = new ArrayList<SQLHistory>(); - - for (SQLHistory sqlHistory : sqlHistoryList) { - if (i < limit) { - revSqLHistoryList.add(sqlHistory); - } - i++; - } - return revSqLHistoryList; - } - - @Override - public void setSQLHistoryList(List<SQLHistory> sqlHistoryList) { - _sqlHistoryList = sqlHistoryList; - } -} diff --git a/db.core/src/org/netbeans/modules/db/sql/history/SQLHistoryPersistenceManager.java b/db.core/src/org/netbeans/modules/db/sql/history/SQLHistoryPersistenceManager.java deleted file mode 100644 --- a/db.core/src/org/netbeans/modules/db/sql/history/SQLHistoryPersistenceManager.java +++ /dev/null @@ -1,572 +0,0 @@ -/* - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. - * - * Copyright 1997-2010 Oracle and/or its affiliates. All rights reserved. - * - * Oracle and Java are registered trademarks of Oracle and/or its affiliates. - * Other names may be trademarks of their respective owners. - * - * The contents of this file are subject to the terms of either the GNU - * General Public License Version 2 only ("GPL") or the Common - * Development and Distribution License("CDDL") (collectively, the - * "License"). You may not use this file except in compliance with the - * License. You can obtain a copy of the License at - * http://www.netbeans.org/cddl-gplv2.html - * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the - * specific language governing permissions and limitations under the - * License. When distributing the software, include this License Header - * Notice in each file and include the License file at - * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the GPL Version 2 section of the License file that - * accompanied this code. If applicable, add the following below the - * License Header, with the fields enclosed by brackets [] replaced by - * your own identifying information: - * "Portions Copyrighted [year] [name of copyright owner]" - * - * Contributor(s): - * - * The Original Software is NetBeans. The Initial Developer of the Original - * Software is Sun Microsystems, Inc. Portions Copyright 1997-2010 Sun - * Microsystems, Inc. All Rights Reserved. - * - * If you wish your version of this file to be governed by only the CDDL - * or only the GPL Version 2, indicate your decision by adding - * "[Contributor] elects to include this software in this distribution - * under the [CDDL or GPL Version 2] license." If you do not indicate a - * single choice of license, a recipient has the option to distribute - * your version of this file under either the CDDL, the GPL Version 2 or - * to extend the choice of license to its licensees as provided above. - * However, if you add GPL Version 2 code and therefore, elected the GPL - * Version 2 license, then the option applies only if the new code is - * made subject to such option by the copyright holder. - */ -package org.netbeans.modules.db.sql.history; - -import java.io.File; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.io.OutputStreamWriter; -import java.io.PrintWriter; -import java.text.DateFormat; -import java.text.ParseException; -import java.util.ArrayList; -import java.util.Calendar; -import java.util.Collections; -import java.util.Date; -import java.util.List; -import org.openide.util.Exceptions; -import org.xml.sax.Attributes; -import java.util.logging.Level; -import java.util.logging.Logger; -import javax.xml.parsers.DocumentBuilder; -import javax.xml.parsers.DocumentBuilderFactory; -import javax.xml.parsers.ParserConfigurationException; -import org.openide.filesystems.FileLock; -import org.openide.filesystems.FileObject; -import org.openide.filesystems.FileSystem; -import org.openide.filesystems.FileUtil; -import org.openide.loaders.DataFolder; -import org.openide.loaders.XMLDataObject; -import org.openide.util.NbPreferences; -import org.openide.xml.EntityCatalog; -import org.openide.xml.XMLUtil; -import org.w3c.dom.Document; -import org.w3c.dom.Element; -import org.w3c.dom.NamedNodeMap; -import org.w3c.dom.Node; -import org.w3c.dom.NodeList; -import org.w3c.dom.Text; -import org.xml.sax.ContentHandler; -import org.xml.sax.InputSource; -import org.xml.sax.SAXException; -import org.xml.sax.XMLReader; -import org.xml.sax.helpers.DefaultHandler; - -/** - * Manage creation and updates to persisted SQL statements - * - * @author John Baker - */ -public class SQLHistoryPersistenceManager { - private static final int READ = 0; - private static final int ADD = 1; - private static final int REMOVE = 2; - private static final int CREATE = 3; - public static final Logger LOGGER = Logger.getLogger(SQLHistoryPersistenceManager.class.getName()); - private static SQLHistoryPersistenceManager _instance = null; - private static Document document; - private List<SQLHistory> sqlHistoryList; - private int numElemsToRemove = 0; - - private SQLHistoryPersistenceManager() { - } - - public static SQLHistoryPersistenceManager getInstance() { - if (null == _instance) { - _instance = new SQLHistoryPersistenceManager(); - } - return _instance; - } - - public void removeHistoryFile(FileObject historyRoot) { - try { - FileObject folder = DataFolder.findFolder(historyRoot).getPrimaryFile(); - String fn = FileUtil.getFileDisplayName(folder) + File.separator + SQLHistoryManager.SQL_HISTORY_FILE_NAME; - FileObject historyFo = FileUtil.toFileObject(FileUtil.normalizeFile(new File(fn))); - historyFo.delete(); - } catch (IOException ex) { - Exceptions.printStackTrace(ex); - } - - } - - public void create(FileObject historyFileObject, List<SQLHistory> sqlHistoryList) throws SQLHistoryException { - try { - this.sqlHistoryList = sqlHistoryList; - DataFolder df = DataFolder.findFolder(historyFileObject); - int action = df.getChildren().length == 0 ? CREATE : ADD; - AtomicFileAction writer = new AtomicFileAction(df, null, action, sqlHistoryList); - df.getPrimaryFile().getFileSystem().runAtomicAction(writer); - } catch (IOException ex) { - throw new SQLHistoryException(ex.getLocalizedMessage(), ex); - } - } - - public List<SQLHistory> retrieve(FileObject historyFileObject) throws ClassNotFoundException, SQLHistoryException { - Handler handler = null; - int limit; - String limitUser = NbPreferences.forModule(SQLHistoryPersistenceManager.class).get("SQL_STATEMENTS_SAVED_FOR_HISTORY", ""); - if (!limitUser.isEmpty()) { // NOI18N - try { - limit = Integer.parseInt(limitUser); - } catch (NumberFormatException nfe) { - limit = Integer.parseInt(SQLHistoryManager.SAVE_STATEMENTS_MAX_LIMIT_ENTERED); - } - } else { - limit = Integer.parseInt(SQLHistoryManager.SAVE_STATEMENTS_MAX_LIMIT_ENTERED); - } - try { - handler = new Handler(limit); - DataFolder df = DataFolder.findFolder(historyFileObject); - AtomicFileAction reader = new AtomicFileAction(df, handler, READ, null); - df.getPrimaryFile().getFileSystem().runAtomicAction(reader); - - } catch (IOException ex) { - LOGGER.log(Level.FINE, ex.getLocalizedMessage(), ex); - sqlHistoryList = handler.getXmlSqlHistoryList(); - throw new SQLHistoryException(); - } - if (handler != null) { - return handler.getXmlSqlHistoryList(); - } else { - return new ArrayList<SQLHistory>(); - } - } - - public List<SQLHistory> retrieve() { - return sqlHistoryList; - } - - public void setNumElemsToRemove(int elemsToRemove) { - numElemsToRemove = elemsToRemove; - } - - public int getNumElemsToRemove() { - return numElemsToRemove; - } - - public List<SQLHistory> updateSQLSaved(int limit, FileObject historyFileObject) throws SQLHistoryException { - List<SQLHistory> updatedSQLHistoryList = null; - try { - if (historyFileObject == null) { - return new ArrayList<SQLHistory>(); - } - updatedSQLHistoryList = retrieve(historyFileObject); - // Remove elements from list based on the number of statements to save that is set in the SQL History dialog - if (limit < updatedSQLHistoryList.size()) { - numElemsToRemove = updatedSQLHistoryList.size() - limit; - boolean containsElems = true; - containsElems = !updatedSQLHistoryList.isEmpty(); - if (containsElems && numElemsToRemove == updatedSQLHistoryList.size()) { - // remove all - DataFolder df = DataFolder.findFolder(historyFileObject); - List<SQLHistory> emptyList = Collections.emptyList(); - AtomicFileAction writer = new AtomicFileAction(df, null, CREATE, emptyList); - df.getPrimaryFile().getFileSystem().runAtomicAction(writer); - } else if (containsElems && (limit == 0 || numElemsToRemove >= 0)) { - DataFolder df = DataFolder.findFolder(historyFileObject); - AtomicFileAction modifier = new AtomicFileAction(df, null, REMOVE, updatedSQLHistoryList); - df.getPrimaryFile().getFileSystem().runAtomicAction(modifier); - } - } - updatedSQLHistoryList = retrieve(historyFileObject); - } catch (ClassNotFoundException ex) { - throw new SQLHistoryException(ex.getLocalizedMessage(), ex); - } catch (IOException ex) { - throw new SQLHistoryException(ex.getLocalizedMessage(), ex); - } - return updatedSQLHistoryList; - } - - private static final class AtomicFileAction implements FileSystem.AtomicAction { - List<SQLHistory> sqlHistoryList; - DataFolder parent; - boolean remove; - FileObject data; - Handler handler; - int actionType; - - AtomicFileAction(DataFolder parent, Handler handler, int actionType, List<SQLHistory> sqlHistoryList) { - this.parent = parent; - this.handler = handler; - this.sqlHistoryList = sqlHistoryList; - this.actionType = actionType; - } - - @Override - public void run() throws IOException { - FileLock lck = null; - OutputStream ostm = null; - PrintWriter writer = null; - XmlWriter xmlWriter = null; - DocumentBuilderFactory factory = null; - DocumentBuilder builder = null; - try { - FileObject folder = parent.getPrimaryFile(); - String fn = FileUtil.getFileDisplayName(folder) + File.separator + SQLHistoryManager.SQL_HISTORY_FILE_NAME; - // Read, Write or Update the persisted SQL file - switch (actionType) { - case READ: - FileObject historyFo = FileUtil.toFileObject(FileUtil.normalizeFile(new File(fn))); - XMLDataObject obj = (XMLDataObject) XMLDataObject.find(historyFo); - InputSource inputSource = new InputSource(obj.getPrimaryFile().getInputStream()); - inputSource.setSystemId(historyFo.getURL().toExternalForm()); - XMLReader reader = XMLUtil.createXMLReader(); - reader.setContentHandler(handler); - reader.setErrorHandler(handler); - reader.setEntityResolver(EntityCatalog.getDefault()); - reader.parse(inputSource); - break; - case ADD: - factory = DocumentBuilderFactory.newInstance(); - builder = factory.newDocumentBuilder(); - data = FileUtil.toFileObject(FileUtil.normalizeFile(new File(fn))); - InputStream inputStream = data.getInputStream(); - document = builder.parse(inputStream); - inputStream.close(); - lck = data.lock(); - ostm = data.getOutputStream(lck); - writer = new PrintWriter(new OutputStreamWriter(ostm, "UTF8")); //NOI18N - // Create or update then write the DOM - xmlWriter = new XmlWriter(data, sqlHistoryList, writer); - xmlWriter.write(xmlWriter.createElements(document), ""); // NOI18N - break; - case CREATE: - factory = DocumentBuilderFactory.newInstance(); - builder = factory.newDocumentBuilder(); - if (new File(fn).exists()) { - data = folder.getFileObject(SQLHistoryManager.SQL_HISTORY_FILE_NAME); - } else { - data = folder.createData(SQLHistoryManager.SQL_HISTORY_FILE_NAME); - } - lck = data.lock(); - ostm = data.getOutputStream(lck); - writer = new PrintWriter(new OutputStreamWriter(ostm, "UTF8")); //NOI18N - document = builder.newDocument(); - xmlWriter = new XmlWriter(data, sqlHistoryList, writer); - xmlWriter.write(); - // Create or update then write the DOM - xmlWriter = new XmlWriter(data, sqlHistoryList, writer); - xmlWriter.write(xmlWriter.createElements(document), ""); // NOI18N - break; - case REMOVE: - factory = DocumentBuilderFactory.newInstance(); - builder = factory.newDocumentBuilder(); - if (folder.getChildren().length > 0) { - data = FileUtil.toFileObject(FileUtil.normalizeFile(new File(fn))); - InputStream is = data.getInputStream(); - document = builder.parse(is); - is.close(); - lck = data.lock(); - ostm = data.getOutputStream(lck); - writer = new PrintWriter(new OutputStreamWriter(ostm, "UTF8")); //NOI18N - } - // Create or update then write the DOM - xmlWriter = new XmlWriter(data, sqlHistoryList, writer); - xmlWriter.write(); // NOI18N - xmlWriter.write(xmlWriter.removeElements(document), ""); // NOI18N - break; - } - } catch (ParserConfigurationException ex) { - LOGGER.log(Level.INFO, ex.getMessage()); - throw new IOException(ex.getLocalizedMessage(), ex); - - } catch (SAXException ex) { - LOGGER.log(Level.INFO, ex.getMessage()); - throw new IOException(ex.getLocalizedMessage(),ex); - } finally { - if (writer != null) { - writer.flush(); - writer.close(); - writer = null; - } - if (ostm != null) { - ostm.close(); - ostm = null; - } - if (lck != null) { - lck.releaseLock(); - } - } - } - } - - private static final class XmlWriter { - private PrintWriter pw; - private List<SQLHistory> sqlHistoryList; - - public XmlWriter(FileObject data, List<SQLHistory> sqlHistoryList, PrintWriter pw) { - this.sqlHistoryList = sqlHistoryList; - this.pw = pw; - } - - /** - * - * create XML elements from SQL statements - */ - private Node createElements(Document document) { - Element newNode = null; - Element nameNode = null; - if (null == document.getDocumentElement()) { - newNode = document.createElement("history"); // NOI18N - for (SQLHistory sqlHistory : sqlHistoryList) { - nameNode = document.createElement("sql"); // NOI18N - nameNode.appendChild(document.createTextNode(sqlHistory.getSql())); - nameNode.setAttribute("url", sqlHistory.getUrl()); // NOI18N - nameNode.setAttribute("date", new Long(sqlHistory.getDate().getTime()).toString()); // NOI18N - newNode.appendChild(nameNode); - } - document.adoptNode(newNode); - } else { - newNode = document.getDocumentElement(); - for (SQLHistory sqlHistory : sqlHistoryList) { - nameNode = document.createElement("sql"); // NOI18N - nameNode.appendChild(document.createTextNode(sqlHistory.getSql())); - nameNode.setAttribute("url", sqlHistory.getUrl()); // NOI18N - nameNode.setAttribute("date", new Long(sqlHistory.getDate().getTime()).toString()); // NOI18N - newNode.insertBefore(nameNode, newNode.getFirstChild()); - } - } - return newNode; - } - - /** - * - * remove XML elements when the number of statements to save is reduced in the SQL History dialog - */ - private Node removeElements(Document document) { - NodeList nodes = null; - Element history = document.getDocumentElement(); - if (null != history) { - nodes = history.getElementsByTagName("sql"); - int elemsToRemove = SQLHistoryPersistenceManager.getInstance().getNumElemsToRemove(); - // Statements to save was set to 0 - if (elemsToRemove == 0) { - for (int i = 0; i < nodes.getLength(); i++) { - if (nodes.item(0) != null) { - history.removeChild(nodes.item(0)); - } - } - } - // Remove elements from the DOM - for (int i = 0; i < elemsToRemove; i++) { - if (nodes.item(0) != null) { - history.removeChild(nodes.item(nodes.getLength() - 1)); - } - } - } - return history; - } - - private void write() { - pw.println("<?xml version='1.0' encoding='UTF-8' ?>"); - } - - /** - * - * write the SQL statements as xml - */ - private void write(Node node, String indent) { - switch (node.getNodeType()) { - case Node.DOCUMENT_NODE: { - Document doc = (Document) node; - pw.println(indent + "<?xml version='1.0'?>"); // NOI18N - Node child = doc.getFirstChild(); - while (child != null) { - write(child, indent); - child = child.getNextSibling(); - } - break; - } - case Node.ELEMENT_NODE: { - Element elt = (Element) node; - pw.print(indent + "<" + elt.getTagName()); - NamedNodeMap attrs = elt.getAttributes(); - for (int i = 0; i < attrs.getLength(); i++) { - Node a = attrs.item(i); - pw.print(" " + a.getNodeName() + "='" + fixup(a.getNodeValue()) + "'"); // NOI18N - } - pw.println(">"); // NOI18N - String newindent = indent + " "; // NOI18N - Node child = elt.getFirstChild(); - while (child != null) { - write(child, newindent); - child = child.getNextSibling(); - } - - pw.println(indent + "</" + elt.getTagName() + ">"); // NOI18N - break; - } - case Node.TEXT_NODE: { - Text textNode = (Text) node; - String text = textNode.getData().trim(); - if ((text != null) && text.length() > 0) { - pw.println(indent + fixup(text)); - } - break; - } - default: - LOGGER.log(Level.INFO, "Ignoring node: " + node.getClass().getName()); // NOI18N - break; - } - - } - - private String fixup(String s) { - StringBuilder sb = new StringBuilder(); - int len = s.length(); - for (int i = 0; i < len; i++) { - char c = s.charAt(i); - switch (c) { - default: - sb.append(c); - break; - case '<': // NOI18N - sb.append("<"); // NOI18N - break; - case '>': // NOI18N - sb.append(">"); // NOI18N - break; - case '&': // NOI18N - sb.append("&"); // NOI18N - break; - case '"': // NOI18N - sb.append("""); // NOI18N - break; - case '\'': // NOI18N - sb.append("'"); // NOI18N - break; - } - } - return sb.toString(); - } - } - - /** - * SAX handler for reading the XML file. - */ - private static final class Handler extends DefaultHandler implements ContentHandler { - - private static final String ELEMENT_SQL = "sql"; // NOI18N - private static final String ATTR_URL_PROPERTY_VALUE = "url"; // NOI18N - private static final String ATTR_DATE_PROPERTY_VALUE = "date"; // NOI18N - private static String url; - private static StringBuilder sql; - private static Date date; - boolean matchingUrl = false; - private List<SQLHistory> xmlSqlHistoryList = new ArrayList<SQLHistory>(); - static boolean isSql = false; - private int limit; - private static Calendar calendar = Calendar.getInstance(); - - public Handler(int limit) { - this.limit = limit; - } - - @Override - public void startElement(String uri, String localName, String qName, Attributes attrs) throws SAXException { - if (ELEMENT_SQL.equals(qName)) { - isSql = true; - url = attrs.getValue(ATTR_URL_PROPERTY_VALUE); - try { - calendar.setTimeInMillis(Long.parseLong(attrs.getValue(ATTR_DATE_PROPERTY_VALUE))); - date = calendar.getTime(); - } catch (NumberFormatException nfe) { - // #152486 - previously date stored in text format - try { - date = DateFormat.getDateTimeInstance(DateFormat.SHORT, DateFormat.SHORT).parse(attrs.getValue(ATTR_DATE_PROPERTY_VALUE)); - } catch (ParseException pe) { - // # 152486; Date stored is not parsable, so reset the date to the current timestamp - date = calendar.getTime(); - } - } - } else { - isSql = false; - } - } - - @Override - public void endElement(String uri, String localName, String qName) { - if (ELEMENT_SQL.equals(qName)) { - if (url != null && sql != null && date != null) { - addHistory(url, sql.toString(), date); - reset(); - } - } - } - - private static void reset() { - // reset data - url = null; - date = null; - sql = null; - } - - private void addHistory(String url, String sql, Date date) { - if ((xmlSqlHistoryList.size() <= limit) || limit == 0) { - xmlSqlHistoryList.add(new SQLHistory(url, sql, date)); - setXmlSqlHistoryList(xmlSqlHistoryList); - } else { - // remove a statement from the end of the list - xmlSqlHistoryList.remove(xmlSqlHistoryList.size() - 1); - } - } - - @Override - public void characters(char buf[], int offset, int length) { - if (isSql) { - String parsedValue = new String(buf, offset, length); - if (sql == null) { - sql = new StringBuilder(); - sql.append(parsedValue); - } else { - sql.append(parsedValue); - } - } - } - - public void setXmlSqlHistoryList(List<SQLHistory> sqlHistoryList) { - xmlSqlHistoryList = sqlHistoryList; - } - - public List<SQLHistory> getXmlSqlHistoryList() { - if (xmlSqlHistoryList == null) { - return new ArrayList<SQLHistory>(); - } else { - return xmlSqlHistoryList; - } - } - } -} diff --git a/db.core/src/org/netbeans/modules/db/sql/history/jaxb.index b/db.core/src/org/netbeans/modules/db/sql/history/jaxb.index new file mode 100644 --- /dev/null +++ b/db.core/src/org/netbeans/modules/db/sql/history/jaxb.index @@ -0,0 +1,2 @@ +SQLHistory +SQLHistoryEntry \ No newline at end of file diff --git a/db.core/test/unit/src/org/netbeans/modules/db/sql/history/SQLHistoryManagerTest.java b/db.core/test/unit/src/org/netbeans/modules/db/sql/history/SQLHistoryManagerTest.java --- a/db.core/test/unit/src/org/netbeans/modules/db/sql/history/SQLHistoryManagerTest.java +++ b/db.core/test/unit/src/org/netbeans/modules/db/sql/history/SQLHistoryManagerTest.java @@ -41,10 +41,10 @@ */ package org.netbeans.modules.db.sql.history; -import java.io.File; import java.io.IOException; import java.text.DateFormat; import java.text.ParseException; +import java.util.Date; import org.netbeans.junit.NbTestCase; import org.netbeans.junit.NbTestSuite; import org.openide.filesystems.FileObject; @@ -62,8 +62,10 @@ * @author John Baker */ public class SQLHistoryManagerTest extends NbTestCase { + public static final String SQL_HISTORY_FOLDER = "Databases/SQLHISTORY"; // NOI18N public static final String SQL_HISTORY_FILE_NAME = "sql_history.xml"; // NOI18N + /** Default constructor. * @param testName name of particular test case */ @@ -107,107 +109,51 @@ } public void testUpdateListRemoveEqualNumber() { - try { - FileObject root = FileUtil.toFileObject(getWorkDir()); - // Create a list of SQL statements - SQLHistoryManager.getInstance().saveSQL(new SQLHistory("jdbc:// derby", "select * from TRAVEL.TRIP", DateFormat.getInstance().parse("07/10/96 4:5 PM, PDT"))); - SQLHistoryManager.getInstance().saveSQL(new SQLHistory("jdbc:// postgres", "select * from TRAVEL.TRIP", DateFormat.getInstance().parse("07/10/96 4:5 PM, PDT"))); - // Save SQL - SQLHistoryManager.getInstance().save(root); - String historyFileRootPath = FileUtil.getFileDisplayName(root) + File.separator + "Databases" + File.separator + "SQLHISTORY"; - FileObject historyFileObject = FileUtil.toFileObject(new File(historyFileRootPath)); - String historyFilePath = historyFileRootPath + File.separator + SQL_HISTORY_FILE_NAME; - // Limit to 2 SQL statements - SQLHistoryManager.getInstance().updateList(2, historyFilePath , historyFileObject); - assertEquals(0, SQLHistoryManager.getInstance().getSQLHistory().size()); - } catch (SQLHistoryException ex) { - Exceptions.printStackTrace(ex); - } catch (IOException ex) { - Exceptions.printStackTrace(ex); - } catch (ParseException ex) { - Exceptions.printStackTrace(ex); - } + SQLHistoryManager.getInstance().saveSQL(new SQLHistoryEntry("jdbc:// derby", "select * from TRAVEL.TRIP", new Date())); + SQLHistoryManager.getInstance().saveSQL(new SQLHistoryEntry("jdbc:// postgres", "select * from TRAVEL.TRIP", new Date())); + SQLHistoryManager.getInstance().setListSize(2); + assertEquals(2, SQLHistoryManager.getInstance().getSQLHistory().size()); } public void testUpdateListRemoveLessNumber3() { - try { - FileObject root = FileUtil.toFileObject(getWorkDir()); + SQLHistoryManager.getInstance().setListSize(100); + SQLHistoryManager.getInstance().getSQLHistory().clear(); // Create a list of SQL statements - SQLHistoryManager.getInstance().saveSQL(new SQLHistory("jdbc:// derby", "select * from TRAVEL.TRIP", DateFormat.getInstance().parse("07/10/96 4:5 PM, PDT"))); - SQLHistoryManager.getInstance().saveSQL(new SQLHistory("jdbc:// postgres", "select * from TRAVEL.TRIPTYPE", DateFormat.getInstance().parse("07/10/96 4:5 PM, PDT"))); - SQLHistoryManager.getInstance().saveSQL(new SQLHistory("jdbc:// postgres", "select * from TRAVEL.TRIP", DateFormat.getInstance().parse("07/10/96 4:5 PM, PDT"))); - SQLHistoryManager.getInstance().saveSQL(new SQLHistory("jdbc:// postgres", "select * from TRAVEL.TRIP", DateFormat.getInstance().parse("07/10/96 4:5 PM, PDT"))); - SQLHistoryManager.getInstance().saveSQL(new SQLHistory("jdbc:// postgres", "select * from TRAVEL.PERSON", DateFormat.getInstance().parse("07/10/96 4:5 PM, PDT"))); - assertEquals(5, SQLHistoryManager.getInstance().getSQLHistory().size()); - // Save SQL - SQLHistoryManager.getInstance().save(root); - String historyFilePath = FileUtil.getFileDisplayName(root) + File.separator + "Databases" + File.separator + "SQLHISTORY"; - FileObject historyFileObject = root.getFileObject(SQL_HISTORY_FOLDER); - // Limit to 3 SQL statements - SQLHistoryPersistenceManager.getInstance().updateSQLSaved(3, historyFileObject); - assertEquals(3, SQLHistoryPersistenceManager.getInstance().retrieve(historyFileObject).size()); - } catch (SQLHistoryException ex) { - Exceptions.printStackTrace(ex); - } catch (IOException ex) { - Exceptions.printStackTrace(ex); - } catch (ClassNotFoundException ex) { - Exceptions.printStackTrace(ex); - } catch (ParseException ex) { - Exceptions.printStackTrace(ex); - } + SQLHistoryManager.getInstance().saveSQL(new SQLHistoryEntry("jdbc:// derby", "select * from TRAVEL.TRIP", new Date())); + SQLHistoryManager.getInstance().saveSQL(new SQLHistoryEntry("jdbc:// postgres", "select * from TRAVEL.TRIPTYPE", new Date())); + SQLHistoryManager.getInstance().saveSQL(new SQLHistoryEntry("jdbc:// postgres", "select * from TRAVEL.TRIP", new Date())); + SQLHistoryManager.getInstance().saveSQL(new SQLHistoryEntry("jdbc:// postgres", "select * from TRAVEL.TRIP", new Date())); + SQLHistoryManager.getInstance().saveSQL(new SQLHistoryEntry("jdbc:// postgres", "select * from TRAVEL.PERSON", new Date())); + assertEquals(4, SQLHistoryManager.getInstance().getSQLHistory().size()); + SQLHistoryManager.getInstance().setListSize(3); + assertEquals(3, SQLHistoryManager.getInstance().getSQLHistory().size()); } public void testUpdateListRemoveLessNumber1() { - try { - FileObject root = FileUtil.toFileObject(getWorkDir()); + SQLHistoryManager.getInstance().setListSize(100); + SQLHistoryManager.getInstance().getSQLHistory().clear(); // Create a list of SQL statements - SQLHistoryManager.getInstance().saveSQL(new SQLHistory("jdbc:// derby", "select * from TRAVEL.TRIP", DateFormat.getInstance().parse("07/10/96 4:5 PM, PDT"))); - SQLHistoryManager.getInstance().saveSQL(new SQLHistory("jdbc:// postgres1", "select * from TRAVEL.TRIP", DateFormat.getInstance().parse("07/10/96 4:5 PM, PDT"))); - SQLHistoryManager.getInstance().saveSQL(new SQLHistory("jdbc:// postgres2", "select * from TRAVEL.TRIP", DateFormat.getInstance().parse("07/10/96 4:5 PM, PDT"))); - SQLHistoryManager.getInstance().saveSQL(new SQLHistory("jdbc:// postgres3", "select * from TRAVEL.TRIP", DateFormat.getInstance().parse("07/10/96 4:5 PM, PDT"))); - SQLHistoryManager.getInstance().saveSQL(new SQLHistory("jdbc:// postgres4", "select * from TRAVEL.TRIP", DateFormat.getInstance().parse("07/10/96 4:5 PM, PDT"))); - // Save SQL - SQLHistoryManager.getInstance().save(root); - String historyFilePath = FileUtil.getFileDisplayName(root) + File.separator + "Databases" + File.separator + "SQLHISTORY"; - FileObject historyFileObject = FileUtil.toFileObject(new File(historyFilePath)); - // Limit to 1 SQL statement - SQLHistoryManager.getInstance().updateList(1, historyFilePath , historyFileObject); + SQLHistoryManager.getInstance().saveSQL(new SQLHistoryEntry("jdbc:// derby", "select * from TRAVEL.TRIP", new Date())); + SQLHistoryManager.getInstance().saveSQL(new SQLHistoryEntry("jdbc:// postgres1", "select * from TRAVEL.TRIP", new Date())); + SQLHistoryManager.getInstance().saveSQL(new SQLHistoryEntry("jdbc:// postgres2", "select * from TRAVEL.TRIP", new Date())); + SQLHistoryManager.getInstance().saveSQL(new SQLHistoryEntry("jdbc:// postgres3", "select * from TRAVEL.TRIP", new Date())); + SQLHistoryManager.getInstance().saveSQL(new SQLHistoryEntry("jdbc:// postgres4", "select * from TRAVEL.TRIP", new Date())); + assertEquals(5, SQLHistoryManager.getInstance().getSQLHistory().size()); + SQLHistoryManager.getInstance().setListSize(1); assertEquals(1, SQLHistoryManager.getInstance().getSQLHistory().size()); - } catch (SQLHistoryException ex) { - Exceptions.printStackTrace(ex); - } catch (IOException ex) { - Exceptions.printStackTrace(ex); - } catch (ParseException ex) { - Exceptions.printStackTrace(ex); - } } public void testUpdateListRemoveAll() { - try { - FileObject root = FileUtil.toFileObject(getWorkDir()); + SQLHistoryManager.getInstance().setListSize(100); + SQLHistoryManager.getInstance().getSQLHistory().clear(); // Create a list of SQL statements - SQLHistoryManager.getInstance().saveSQL(new SQLHistory("jdbc:// derby", "select * from TRAVEL.TRIP", DateFormat.getInstance().parse("07/10/96 4:5 PM, PDT"))); - SQLHistoryManager.getInstance().saveSQL(new SQLHistory("jdbc:// postgres1", "select * from TRAVEL.TRIP", DateFormat.getInstance().parse("07/10/96 4:5 PM, PDT"))); - SQLHistoryManager.getInstance().saveSQL(new SQLHistory("jdbc:// postgres2", "select * from TRAVEL.TRIP", DateFormat.getInstance().parse("07/10/96 4:5 PM, PDT"))); - SQLHistoryManager.getInstance().saveSQL(new SQLHistory("jdbc:// postgres3", "select * from TRAVEL.TRIP", DateFormat.getInstance().parse("07/10/96 4:5 PM, PDT"))); - SQLHistoryManager.getInstance().saveSQL(new SQLHistory("jdbc:// postgres4", "select * from TRAVEL.TRIP", DateFormat.getInstance().parse("07/10/96 4:6 PM, PDT"))); - // Save SQL - SQLHistoryManager.getInstance().save(root); - String historyFilePath = FileUtil.getFileDisplayName(root) + File.separator + "Databases" + File.separator + "SQLHISTORY"; - FileObject historyFileObject = FileUtil.toFileObject(new File(historyFilePath)); - // Limit to 0 SQL statements - SQLHistoryManager.getInstance().updateList(0, historyFilePath, historyFileObject); - SQLHistoryPersistenceManager.getInstance().updateSQLSaved(0, historyFileObject); - assertEquals(0, SQLHistoryPersistenceManager.getInstance().retrieve(historyFileObject).size()); - } catch (SQLHistoryException ex) { - Exceptions.printStackTrace(ex); - } catch (IOException ex) { - Exceptions.printStackTrace(ex); - } catch (ClassNotFoundException ex) { - Exceptions.printStackTrace(ex); - } catch (ParseException ex) { - Exceptions.printStackTrace(ex); - } + SQLHistoryManager.getInstance().saveSQL(new SQLHistoryEntry("jdbc:// derby", "select * from TRAVEL.TRIP", new Date())); + SQLHistoryManager.getInstance().saveSQL(new SQLHistoryEntry("jdbc:// postgres1", "select * from TRAVEL.TRIP", new Date())); + SQLHistoryManager.getInstance().saveSQL(new SQLHistoryEntry("jdbc:// postgres2", "select * from TRAVEL.TRIP", new Date())); + SQLHistoryManager.getInstance().saveSQL(new SQLHistoryEntry("jdbc:// postgres3", "select * from TRAVEL.TRIP", new Date())); + SQLHistoryManager.getInstance().saveSQL(new SQLHistoryEntry("jdbc:// postgres4", "select * from TRAVEL.TRIP", new Date())); + assertEquals(5, SQLHistoryManager.getInstance().getSQLHistory().size()); + SQLHistoryManager.getInstance().setListSize(0); + assertEquals(0, SQLHistoryManager.getInstance().getSQLHistory().size()); } - } diff --git a/db.core/test/unit/src/org/netbeans/modules/db/sql/history/SQLHistoryPersistenceManagerTest.java b/db.core/test/unit/src/org/netbeans/modules/db/sql/history/SQLHistoryPersistenceManagerTest.java --- a/db.core/test/unit/src/org/netbeans/modules/db/sql/history/SQLHistoryPersistenceManagerTest.java +++ b/db.core/test/unit/src/org/netbeans/modules/db/sql/history/SQLHistoryPersistenceManagerTest.java @@ -50,6 +50,7 @@ import org.netbeans.junit.NbTestCase; import org.openide.filesystems.FileObject; import org.openide.filesystems.FileUtil; +import org.openide.util.Exceptions; /** * @author John Baker, Jiri Skrivanek @@ -77,30 +78,41 @@ /** Test testExecuteStatements passes if no exceptions occur. */ public void testExecuteStatements() throws Exception { - List<SQLHistory> sqlHistoryList = new ArrayList<SQLHistory>(); - sqlHistoryList.add(new SQLHistory("jdbc:// mysql", "select * from TRAVEL.PERSON", Calendar.getInstance().getTime())); - FileObject fo = FileUtil.toFileObject(getWorkDir()); - sqlHistoryList.add(new SQLHistory("jdbc:// oracle", "select * from PERSON", Calendar.getInstance().getTime())); - SQLHistoryPersistenceManager.getInstance().create(fo, sqlHistoryList); - } + SQLHistoryManager testableManager = new SQLHistoryManager() { - /** Test testMultipleExecutions passes if no exceptions occur. */ - public void testMultipleExecutions() throws Exception { - List<SQLHistory> sqlHistoryList = new ArrayList<SQLHistory>(); - sqlHistoryList.add(new SQLHistory("jdbc:// derby", "select * from TRAVEL.TRIP", Calendar.getInstance().getTime())); - FileObject fo = FileUtil.toFileObject(getWorkDir()); - SQLHistoryPersistenceManager.getInstance().create(fo, sqlHistoryList); - sqlHistoryList.add(new SQLHistory("jdbc:// postgres", "select * from TRAVEL.TRIP", Calendar.getInstance().getTime())); - fo = FileUtil.toFileObject(getWorkDir()); - SQLHistoryPersistenceManager.getInstance().create(fo, sqlHistoryList); + @Override + protected FileObject getConfigRoot() { + try { + return FileUtil.toFileObject(getWorkDir()); + } catch (IOException ex) { + throw new RuntimeException(ex); + } + } + + @Override + protected String getRelativeHistoryPath() { + return ""; + } + + }; + testableManager.getSQLHistory().add(new SQLHistoryEntry("jdbc:// mysql", "select * from TRAVEL.PERSON", Calendar.getInstance().getTime())); + testableManager.getSQLHistory().add(new SQLHistoryEntry("jdbc:// oracle", "select * from PERSON", Calendar.getInstance().getTime())); + testableManager.save(); } /** Tests parsing of date format. */ public void testDateParsing() throws Exception { - URL u = this.getClass().getResource("sql_history.xml"); - FileObject fo = FileUtil.toFileObject(new File(u.toURI())); - List<SQLHistory> sqlHistoryList = SQLHistoryPersistenceManager.getInstance().retrieve(fo.getParent()); - for (SQLHistory sqlHistory : sqlHistoryList) { + final URL u = this.getClass().getResource("sql_history.xml"); + final FileObject fo = FileUtil.toFileObject(new File(u.toURI())); + SQLHistoryManager testableManager = new SQLHistoryManager() { + @Override + protected FileObject getHistoryRoot(boolean create) throws IOException { + return fo; + } + }; + + List<SQLHistoryEntry> sqlHistoryList = new ArrayList<SQLHistoryEntry>(testableManager.getSQLHistory()); + for (SQLHistoryEntry sqlHistory : sqlHistoryList) { assertNotNull(sqlHistory.getDate()); } }