This Bugzilla instance is a read-only archive of historic NetBeans bug reports. To report a bug in NetBeans please follow the project's instructions for reporting issues.

View | Details | Raw Unified | Return to bug 204550
Collapse All | Expand All

(-)a/db.core/src/org/netbeans/modules/db/sql/execute/SQLExecuteHelper.java (-6 / +3 lines)
Lines 44-50 Link Here
44
44
45
package org.netbeans.modules.db.sql.execute;
45
package org.netbeans.modules.db.sql.execute;
46
46
47
import org.netbeans.modules.db.sql.history.SQLHistory;
47
import org.netbeans.modules.db.sql.history.SQLHistoryEntry;
48
import java.util.ArrayList;
48
import java.util.ArrayList;
49
import java.util.Collections;
49
import java.util.Collections;
50
import java.util.Date;
50
import java.util.Date;
Lines 54-61 Link Here
54
import org.netbeans.api.db.explorer.DatabaseConnection;
54
import org.netbeans.api.db.explorer.DatabaseConnection;
55
import org.netbeans.modules.db.dataview.api.DataView;
55
import org.netbeans.modules.db.dataview.api.DataView;
56
import org.netbeans.modules.db.sql.history.SQLHistoryManager;
56
import org.netbeans.modules.db.sql.history.SQLHistoryManager;
57
import org.openide.filesystems.FileObject;
58
import org.openide.filesystems.FileUtil;
59
57
60
/**
58
/**
61
 * Support class for executing SQL statements.
59
 * Support class for executing SQL statements.
Lines 68-74 Link Here
68
66
69
    private static final Logger LOGGER = Logger.getLogger(SQLExecuteHelper.class.getName());
67
    private static final Logger LOGGER = Logger.getLogger(SQLExecuteHelper.class.getName());
70
    private static final boolean LOG = LOGGER.isLoggable(Level.FINE);
68
    private static final boolean LOG = LOGGER.isLoggable(Level.FINE);
71
    private static final FileObject USERDIR = FileUtil.getConfigRoot();
72
    
69
    
73
    /**
70
    /**
74
     * Executes a SQL string, possibly containing multiple statements. Returns the execution
71
     * Executes a SQL string, possibly containing multiple statements. Returns the execution
Lines 119-125 Link Here
119
            DataView view = DataView.create(conn, sql, pageSize);
116
            DataView view = DataView.create(conn, sql, pageSize);
120
117
121
            // Save SQL statements executed for the SQLHistoryManager
118
            // Save SQL statements executed for the SQLHistoryManager
122
            SQLHistoryManager.getInstance().saveSQL(new SQLHistory(url, sql, new Date()));
119
            SQLHistoryManager.getInstance().saveSQL(new SQLHistoryEntry(url, sql, new Date()));
123
120
124
            result = new SQLExecutionResult(info, view);
121
            result = new SQLExecutionResult(info, view);
125
122
Lines 153-159 Link Here
153
        }
150
        }
154
                
151
                
155
        // Persist SQL executed
152
        // Persist SQL executed
156
        SQLHistoryManager.getInstance().save(USERDIR);
153
        SQLHistoryManager.getInstance().save();
157
154
158
        if (!cancelled) {
155
        if (!cancelled) {
159
            return new SQLExecutionResults(results);
156
            return new SQLExecutionResults(results);
(-)a/db.core/src/org/netbeans/modules/db/sql/execute/ui/SQLHistoryPanel.form (-29 / +11 lines)
Lines 21-31 Link Here
21
              <Group type="103" groupAlignment="0" attributes="0">
21
              <Group type="103" groupAlignment="0" attributes="0">
22
                  <Group type="102" attributes="0">
22
                  <Group type="102" attributes="0">
23
                      <Group type="103" groupAlignment="0" attributes="0">
23
                      <Group type="103" groupAlignment="0" attributes="0">
24
                          <Component id="jScrollPane1" pref="655" max="32767" attributes="0"/>
24
                          <Component id="jScrollPane1" pref="645" max="32767" attributes="0"/>
25
                          <Group type="102" attributes="0">
25
                          <Group type="102" attributes="0">
26
                              <Component id="jLabel1" min="-2" max="-2" attributes="0"/>
26
                              <Component id="jLabel1" min="-2" max="-2" attributes="0"/>
27
                              <EmptySpace type="unrelated" max="-2" attributes="0"/>
27
                              <EmptySpace type="unrelated" max="-2" attributes="0"/>
28
                              <Component id="connectionUrlComboBox" pref="306" max="32767" attributes="0"/>
28
                              <Component id="connectionUrlComboBox" pref="301" max="32767" attributes="0"/>
29
                              <EmptySpace type="separate" max="-2" attributes="0"/>
29
                              <EmptySpace type="separate" max="-2" attributes="0"/>
30
                              <Component id="jLabel2" min="-2" max="-2" attributes="0"/>
30
                              <Component id="jLabel2" min="-2" max="-2" attributes="0"/>
31
                              <EmptySpace type="unrelated" max="-2" attributes="0"/>
31
                              <EmptySpace type="unrelated" max="-2" attributes="0"/>
Lines 65-71 Link Here
65
              <Group type="103" groupAlignment="0" attributes="0">
65
              <Group type="103" groupAlignment="0" attributes="0">
66
                  <Component id="insertSQLButton" alignment="0" min="-2" max="-2" attributes="0"/>
66
                  <Component id="insertSQLButton" alignment="0" min="-2" max="-2" attributes="0"/>
67
                  <Group type="102" alignment="1" attributes="0">
67
                  <Group type="102" alignment="1" attributes="0">
68
                      <Component id="jScrollPane1" pref="168" max="32767" attributes="0"/>
68
                      <Component id="jScrollPane1" pref="268" max="32767" attributes="0"/>
69
                      <EmptySpace max="-2" attributes="0"/>
69
                      <EmptySpace max="-2" attributes="0"/>
70
                      <Group type="103" groupAlignment="3" attributes="0">
70
                      <Group type="103" groupAlignment="3" attributes="0">
71
                          <Component id="sqlLimitTextField" alignment="3" min="-2" max="-2" attributes="0"/>
71
                          <Component id="sqlLimitTextField" alignment="3" min="-2" max="-2" attributes="0"/>
Lines 90-100 Link Here
90
      </Properties>
90
      </Properties>
91
    </Component>
91
    </Component>
92
    <Component class="javax.swing.JComboBox" name="connectionUrlComboBox">
92
    <Component class="javax.swing.JComboBox" name="connectionUrlComboBox">
93
      <Properties>
94
        <Property name="renderer" type="javax.swing.ListCellRenderer" editor="org.netbeans.modules.form.RADConnectionPropertyEditor">
95
          <Connection code="new ConnectionUrlRenderer()" type="code"/>
96
        </Property>
97
      </Properties>
98
      <AccessibilityProperties>
93
      <AccessibilityProperties>
99
        <Property name="AccessibleContext.accessibleName" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
94
        <Property name="AccessibleContext.accessibleName" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
100
          <ResourceString bundle="org/netbeans/modules/db/sql/execute/ui/Bundle.properties" key="ASCN_ConnectionCombo" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
95
          <ResourceString bundle="org/netbeans/modules/db/sql/execute/ui/Bundle.properties" key="ASCN_ConnectionCombo" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
Lines 163-199 Link Here
163
      <SubComponents>
158
      <SubComponents>
164
        <Component class="javax.swing.JTable" name="sqlHistoryTable">
159
        <Component class="javax.swing.JTable" name="sqlHistoryTable">
165
          <Properties>
160
          <Properties>
161
            <Property name="autoCreateColumnsFromModel" type="boolean" value="false"/>
166
            <Property name="model" type="javax.swing.table.TableModel" editor="org.netbeans.modules.form.RADConnectionPropertyEditor">
162
            <Property name="model" type="javax.swing.table.TableModel" editor="org.netbeans.modules.form.RADConnectionPropertyEditor">
167
              <Connection code="new HistoryTableModel()" type="code"/>
163
              <Connection code="htm" type="code"/>
168
            </Property>
164
            </Property>
169
            <Property name="columnModel" type="javax.swing.table.TableColumnModel" editor="org.netbeans.modules.form.editors2.TableColumnModelEditor">
165
            <Property name="tableHeader" type="javax.swing.table.JTableHeader" editor="org.netbeans.modules.form.editors2.JTableHeaderEditor">
170
              <TableColumnModel selectionModel="0">
166
              <TableHeader reorderingAllowed="true" resizingAllowed="true"/>
171
                <Column maxWidth="-1" minWidth="-1" prefWidth="-1" resizable="true">
172
                  <Title/>
173
                  <Editor/>
174
                  <Renderer/>
175
                </Column>
176
                <Column maxWidth="-1" minWidth="-1" prefWidth="-1" resizable="true">
177
                  <Title/>
178
                  <Editor/>
179
                  <Renderer/>
180
                </Column>
181
              </TableColumnModel>
182
            </Property>
183
            <Property name="gridColor" type="java.awt.Color" editor="org.netbeans.beaninfo.editors.ColorEditor">
184
              <Color blue="c0" green="c0" id="lightGray" palette="1" red="c0" type="palette"/>
185
            </Property>
167
            </Property>
186
          </Properties>
168
          </Properties>
187
          <AccessibilityProperties>
169
          <AccessibilityProperties>
188
            <Property name="AccessibleContext.accessibleName" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
170
            <Property name="AccessibleContext.accessibleName" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
189
              <ResourceString bundle="org/netbeans/modules/db/sql/execute/ui/Bundle.properties" key="ACSN_History" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
171
              <ResourceString bundle="org/netbeans/modules/db/sql/execute/ui/Bundle.properties" key="ACSN_History" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
190
            </Property>
172
            </Property>
191
            <Property name="AccessibleContext.accessibleDescription" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
173
            <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;&#xa;int dateColumnWidth2 = new JTextField(NbBundle.getMessage(SQLHistoryPanel.class, &quot;LBL_DateTableTitle&quot;) + &quot;XXXXX&quot;).getPreferredSize().width;&#xa;int dateColumnWidth = Math.max(dateColumnWidth1, dateColumnWidth2);&#xa;        &#xa;TableColumnModel sqlHistoryTableTCM = sqlHistoryTable.getColumnModel();&#xa;&#xa;TableColumn sqlHistoryTableColumn;&#xa;&#xa;sqlHistoryTableColumn = new TableColumn(1);&#xa;sqlHistoryTableColumn.setHeaderValue(NbBundle.getMessage(SQLHistoryPanel.class, &quot;LBL_SQLTableTitle&quot;));&#xa;&#xa;sqlHistoryTableTCM.addColumn(sqlHistoryTableColumn);&#xa;&#xa;sqlHistoryTableColumn = new TableColumn(2);&#xa;sqlHistoryTableColumn.setMinWidth(dateColumnWidth);&#xa;sqlHistoryTableColumn.setPreferredWidth(dateColumnWidth);&#xa;sqlHistoryTableColumn.setMaxWidth(dateColumnWidth);&#xa;sqlHistoryTableColumn.setHeaderValue(NbBundle.getMessage(SQLHistoryPanel.class, &quot;LBL_DateTableTitle&quot;));&#xa;sqlHistoryTableColumn.setCellRenderer(new DefaultTableCellRenderer() {&#xa;    public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {&#xa;        if(value instanceof Date) {&#xa;            value = dateTimeFormat.format((Date) value);&#xa;        }&#xa;        return super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);&#xa;    }&#xa;});&#xa;        &#xa;sqlHistoryTableTCM.addColumn(sqlHistoryTableColumn);">
192
              <ResourceString bundle="org/netbeans/modules/db/sql/execute/ui/Bundle.properties" key="ACSD_History" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
174
              <ResourceString bundle="org/netbeans/modules/db/sql/execute/ui/Bundle.properties" key="ACSD_History" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
193
            </Property>
175
            </Property>
194
          </AccessibilityProperties>
176
          </AccessibilityProperties>
195
          <AuxValues>
177
          <AuxValues>
196
            <AuxValue name="JavaCodeGenerator_CreateCodeCustom" type="java.lang.String" value="new JTable() {&#xa;        public Component prepareRenderer(TableCellRenderer renderer,&#xa;                                         int rowIndex, int vColIndex) {&#xa;            Component c = super.prepareRenderer(renderer, rowIndex, vColIndex);&#xa;            if (c instanceof JComponent) {&#xa;                JComponent jc = (JComponent)c;&#xa;                jc.setToolTipText(view.getSQLHistoryTooltipValue(rowIndex, vColIndex));&#xa;            }&#xa;            return c;&#xa;        }&#xa;};"/>
178
            <AuxValue name="JavaCodeGenerator_CreateCodeCustom" type="java.lang.String" value="new JTable() {&#xa;    public Component prepareRenderer(TableCellRenderer renderer,&#xa;        int rowIndex, int vColIndex) {&#xa;        Component c = super.prepareRenderer(renderer, rowIndex, vColIndex);&#xa;        if (c instanceof JComponent) {&#xa;            JComponent jc = (JComponent)c;&#xa;            jc.setToolTipText(getSQLHistoryTooltipValue(sqlHistoryTable, rowIndex, vColIndex));&#xa;        }&#xa;        return c;&#xa;    }&#xa;}"/>
197
          </AuxValues>
179
          </AuxValues>
198
        </Component>
180
        </Component>
199
      </SubComponents>
181
      </SubComponents>
Lines 214-220 Link Here
214
    <Component class="javax.swing.JTextField" name="sqlLimitTextField">
196
    <Component class="javax.swing.JTextField" name="sqlLimitTextField">
215
      <Properties>
197
      <Properties>
216
        <Property name="text" type="java.lang.String" editor="org.netbeans.modules.form.RADConnectionPropertyEditor">
198
        <Property name="text" type="java.lang.String" editor="org.netbeans.modules.form.RADConnectionPropertyEditor">
217
          <Connection code="SQLHistoryManager.SAVE_STATEMENTS_MAX_LIMIT_ENTERED" type="code"/>
199
          <Connection code="Integer.toString(SQLHistoryManager.getInstance().getListSize())" type="code"/>
218
        </Property>
200
        </Property>
219
        <Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
201
        <Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
220
          <Dimension value="[18, 22]"/>
202
          <Dimension value="[18, 22]"/>
Lines 224-230 Link Here
224
        <Property name="AccessibleContext.accessibleName" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
206
        <Property name="AccessibleContext.accessibleName" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
225
          <ResourceString bundle="org/netbeans/modules/db/sql/execute/ui/Bundle.properties" key="ACSN_Save" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
207
          <ResourceString bundle="org/netbeans/modules/db/sql/execute/ui/Bundle.properties" key="ACSN_Save" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
226
        </Property>
208
        </Property>
227
        <Property name="AccessibleContext.accessibleDescription" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
209
        <Property name="AccessibleContext.accessibleDescription" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor" postCode="sqlLimitTextField.setInputVerifier(new InputVerifier() {&#xa;&#xa;            public boolean verify(JComponent input) {&#xa;                JTextField tf = (JTextField) input;&#xa;                return tf.getText().matches(&quot;^\\d+$&quot;);&#xa;            }&#xa;        });">
228
          <ResourceString bundle="org/netbeans/modules/db/sql/execute/ui/Bundle.properties" key="ACSD_Save" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
210
          <ResourceString bundle="org/netbeans/modules/db/sql/execute/ui/Bundle.properties" key="ACSD_Save" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
229
        </Property>
211
        </Property>
230
      </AccessibilityProperties>
212
      </AccessibilityProperties>
(-)a/db.core/src/org/netbeans/modules/db/sql/execute/ui/SQLHistoryPanel.java (-796 / +274 lines)
Lines 39-45 Link Here
39
 * 
39
 * 
40
 * Portions Copyrighted 2009 - 2010 Sun Microsystems, Inc.
40
 * Portions Copyrighted 2009 - 2010 Sun Microsystems, Inc.
41
 */
41
 */
42
43
/*
42
/*
44
 * SQLHistoryPanel.java
43
 * SQLHistoryPanel.java
45
 *
44
 *
Lines 48-299 Link Here
48
package org.netbeans.modules.db.sql.execute.ui;
47
package org.netbeans.modules.db.sql.execute.ui;
49
48
50
import java.awt.Component;
49
import java.awt.Component;
51
import java.awt.Cursor;
52
import java.awt.Window;
53
import java.awt.event.ActionEvent;
50
import java.awt.event.ActionEvent;
54
import java.awt.event.ActionListener;
51
import java.awt.event.ActionListener;
55
import java.awt.event.MouseAdapter;
52
import java.awt.event.MouseAdapter;
56
import java.awt.event.MouseEvent;
53
import java.awt.event.MouseEvent;
57
import java.awt.event.WindowAdapter;
58
import java.awt.event.WindowEvent;
59
import java.text.DateFormat;
54
import java.text.DateFormat;
60
import java.util.ArrayList;
55
import java.util.ArrayList;
61
import java.util.Collections;
62
import java.util.Comparator;
63
import java.util.Date;
56
import java.util.Date;
64
import java.util.HashMap;
65
import java.util.HashSet;
66
import java.util.List;
57
import java.util.List;
67
import java.util.Map;
68
import java.util.Set;
69
import java.util.logging.Level;
58
import java.util.logging.Level;
70
import java.util.logging.Logger;
59
import java.util.logging.Logger;
71
import javax.swing.DefaultComboBoxModel;
60
import javax.swing.DefaultComboBoxModel;
72
import javax.swing.DefaultListCellRenderer;
61
import javax.swing.InputVerifier;
73
import javax.swing.JComponent;
62
import javax.swing.JComponent;
74
import javax.swing.JEditorPane;
63
import javax.swing.JEditorPane;
75
import javax.swing.JLabel;
76
import javax.swing.JList;
77
import javax.swing.JTable;
64
import javax.swing.JTable;
78
import javax.swing.SwingUtilities;
65
import javax.swing.JTextField;
79
import javax.swing.UIManager;
66
import javax.swing.ListSelectionModel;
67
import javax.swing.RowFilter;
68
import javax.swing.RowFilter.Entry;
69
import javax.swing.RowSorter.SortKey;
70
import javax.swing.SortOrder;
80
import javax.swing.event.DocumentEvent;
71
import javax.swing.event.DocumentEvent;
81
import javax.swing.event.DocumentListener;
72
import javax.swing.event.DocumentListener;
73
import javax.swing.event.ListSelectionEvent;
74
import javax.swing.event.ListSelectionListener;
82
import javax.swing.event.TableModelEvent;
75
import javax.swing.event.TableModelEvent;
83
import javax.swing.event.TableModelListener;
76
import javax.swing.event.TableModelListener;
77
import javax.swing.table.AbstractTableModel;
84
import javax.swing.table.DefaultTableCellRenderer;
78
import javax.swing.table.DefaultTableCellRenderer;
85
import javax.swing.table.DefaultTableModel;
86
import javax.swing.table.JTableHeader;
87
import javax.swing.table.TableCellRenderer;
79
import javax.swing.table.TableCellRenderer;
88
import javax.swing.table.TableColumn;
80
import javax.swing.table.TableColumn;
89
import javax.swing.table.TableColumnModel;
81
import javax.swing.table.TableColumnModel;
82
import javax.swing.table.TableRowSorter;
90
import javax.swing.text.BadLocationException;
83
import javax.swing.text.BadLocationException;
91
import javax.swing.text.Caret;
84
import javax.swing.text.Caret;
92
import javax.swing.text.Document;
85
import javax.swing.text.Document;
93
import org.netbeans.api.db.explorer.ConnectionManager;
94
import org.netbeans.api.db.explorer.DatabaseConnection;
95
import org.netbeans.api.editor.EditorRegistry;
86
import org.netbeans.api.editor.EditorRegistry;
96
import org.netbeans.modules.db.sql.history.SQLHistory;
87
import org.netbeans.modules.db.sql.history.SQLHistoryEntry;
97
import org.netbeans.modules.db.sql.history.SQLHistoryException;
98
import org.netbeans.modules.db.sql.history.SQLHistoryManager;
88
import org.netbeans.modules.db.sql.history.SQLHistoryManager;
99
import org.netbeans.modules.db.sql.history.SQLHistoryModel;
100
import org.netbeans.modules.db.sql.history.SQLHistoryModelImpl;
101
import org.netbeans.modules.db.sql.history.SQLHistoryPersistenceManager;
102
import org.netbeans.modules.db.sql.loader.SQLDataLoader;
89
import org.netbeans.modules.db.sql.loader.SQLDataLoader;
103
import org.openide.awt.MouseUtils;
90
import org.openide.awt.MouseUtils;
104
import org.openide.filesystems.FileObject;
105
import org.openide.filesystems.FileUtil;
106
import org.openide.util.Exceptions;
91
import org.openide.util.Exceptions;
107
import org.openide.util.NbBundle;
92
import org.openide.util.NbBundle;
108
import org.openide.util.NbPreferences;
93
import org.openide.util.NotImplementedException;
109
import org.openide.util.RequestProcessor;
110
import org.openide.util.RequestProcessor.Task;
111
94
112
/**
95
/**
113
 *
96
 *
114
 * @author John Baker
97
 * @author John Baker
115
 */
98
 */
116
public class SQLHistoryPanel extends javax.swing.JPanel {
99
public class SQLHistoryPanel extends javax.swing.JPanel {
100
101
    private TableRowSorter<HistoryTableModel> rowSorter;
102
    private HistoryTableModel htm = new HistoryTableModel();
117
    public static final String SAVE_STATEMENTS_CLEARED = ""; // NOI18N  
103
    public static final String SAVE_STATEMENTS_CLEARED = ""; // NOI18N  
118
    public static final int SAVE_STATEMENTS_MAX_LIMIT = 10000; 
119
    public static final int TABLE_DATA_WIDTH_SQL = 125;
120
    public static final Logger LOGGER = Logger.getLogger(SQLHistoryPanel.class.getName());
104
    public static final Logger LOGGER = Logger.getLogger(SQLHistoryPanel.class.getName());
121
    private static final FileObject USERDIR = FileUtil.getConfigRoot();
122
    private static final FileObject historyRoot = USERDIR.getFileObject(SQLHistoryManager.SQL_HISTORY_FOLDER);
123
    private static Object[][] data;
124
    private Set<String> currentConnections = new HashSet<String>();
125
    private SQLHistoryView view;
126
    private JEditorPane editorPane;
105
    private JEditorPane editorPane;
127
    private Map<String,String> urlAliasMap = new HashMap<String, String>();
106
    final private ListSelectionModel sqlTableSelektion;
128
    private Map<String,String> aliasUrlMap = new HashMap<String, String>();
107
    final private DateFormat dateTimeFormat = DateFormat.getDateTimeInstance(DateFormat.SHORT, DateFormat.SHORT);
129
    private static RequestProcessor RP = new RequestProcessor(SQLHistoryPanel.class);
130
    private final Task initTask;
131
108
132
    /** Creates new form SQLHistoryPanel */
109
    /** Creates new form SQLHistoryPanel */
133
    public SQLHistoryPanel(final JEditorPane editorPane) {
110
    public SQLHistoryPanel(final JEditorPane editorPane) {
134
        this.editorPane = editorPane;
111
        this.editorPane = editorPane;
135
112
136
        // dummy model
113
        initComponents();
137
        view = new SQLHistoryView(new SQLHistoryModel() {
114
115
        rowSorter = new TableRowSorter<HistoryTableModel>(htm);
116
        sqlHistoryTable.setRowSorter(rowSorter);
117
        List<SortKey> sortKeys = new ArrayList<SortKey>();
118
        sortKeys.add(new SortKey(2, SortOrder.DESCENDING));
119
        rowSorter.setSortKeys(sortKeys);
120
        rowSorter.setSortsOnUpdates(true);
121
        rowSorter.sort();
122
123
        sqlTableSelektion = sqlHistoryTable.getSelectionModel();
124
125
        updateURLList();
126
127
        htm.addTableModelListener(new TableModelListener() {
138
128
139
            @Override
129
            @Override
140
            public void initialize() {
130
            public void tableChanged(TableModelEvent e) {
131
                updateURLList();
132
            }
133
        });
134
135
        searchTextField.getDocument().addDocumentListener(new DocumentListener() {
136
137
            @Override
138
            public void insertUpdate(DocumentEvent e) {
139
                updateFilter();
141
            }
140
            }
142
141
143
            @Override
142
            @Override
144
            public void setFilter(String filter) {
143
            public void removeUpdate(DocumentEvent e) {
144
                updateFilter();
145
            }
145
            }
146
146
147
            @Override
147
            @Override
148
            public String getFilter() {
148
            public void changedUpdate(DocumentEvent e) {
149
                return ""; // NOI18N
149
                updateFilter();
150
            }
151
152
            @Override
153
            public List<SQLHistory> getSQLHistoryList() throws SQLHistoryException {
154
                return Collections.emptyList();
155
            }
156
157
            @Override
158
            public void setSQLHistoryList(List<SQLHistory> sqlHistoryList) {
159
            }
150
            }
160
        });
151
        });
161
152
162
        initSQLHistoryTableData();
153
        sqlHistoryTable.addMouseListener(new MouseAdapter() {
163
        initComponents();
164
        setupSQLSaveLimit();
165
        initTask = RP.post(new Runnable() {
166
154
167
            @Override
155
            @Override
168
            public void run() {
169
                lazyInit();
170
            }
171
        });
172
    }
173
174
    public void lazyInit() {
175
        view = new SQLHistoryView(new SQLHistoryModelImpl());
176
        for (DatabaseConnection existingConnection : ConnectionManager.getDefault().getConnections()) {
177
            urlAliasMap.put(existingConnection.getDatabaseURL(), existingConnection.getDisplayName());
178
            aliasUrlMap.put(existingConnection.getDisplayName(), existingConnection.getDatabaseURL());
179
        }
180
        // Adjust table column width
181
        SwingUtilities.invokeLater(new Runnable() {
182
183
            @Override
184
            public void run() {
185
                setWaitingState(false);
186
                initSQLHistoryTableData();
187
                initComponentData();
188
                adjustColumnPreferredWidths(sqlHistoryTable);
189
                sqlHistoryTable.revalidate();
190
            }
191
        });
192
    }
193
194
    @Override
195
    public void addNotify() {
196
        super.addNotify();
197
        //show progress for initialize method
198
        final Window w = findWindowParent();
199
        if (w != null) {
200
            w.addWindowListener(new WindowAdapter() {
201
202
                @Override
203
                public void windowOpened(WindowEvent e) {
204
                    setWaitingState(! initTask.isFinished());
205
                }
206
            });
207
        }
208
    }
209
210
    private void setWaitingState(boolean waitingState) {
211
        boolean enabled = !waitingState;
212
        Component parent = getParent();
213
        Component rootPane = getRootPane();
214
        if (parent != null) {
215
            parent.setEnabled(enabled);
216
        }
217
        if (rootPane != null) {
218
            if (enabled) {
219
                rootPane.setCursor(null);
220
            } else {
221
                rootPane.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
222
            }
223
        }
224
    }
225
226
    private Window findWindowParent() {
227
        Component c = this;
228
        while (c != null) {
229
            c = c.getParent();
230
            if (c instanceof Window) {
231
                return (Window) c;
232
            }
233
        }
234
        return null;
235
    }
236
237
    private void setupSQLSaveLimit() {
238
        // SQL statments save limit
239
        String savedLimit = NbPreferences.forModule(SQLHistoryPanel.class).get("SQL_STATEMENTS_SAVED_FOR_HISTORY", ""); // NOI18N
240
        if (null != savedLimit && !savedLimit.equals(SAVE_STATEMENTS_CLEARED)) {
241
            sqlLimitTextField.setText(savedLimit);
242
        } else {
243
            sqlLimitTextField.setText(SQLHistoryManager.SAVE_STATEMENTS_MAX_LIMIT_ENTERED);
244
            savedLimit = SQLHistoryManager.SAVE_STATEMENTS_MAX_LIMIT_ENTERED;
245
            NbPreferences.forModule(SQLHistoryPanel.class).put("SQL_STATEMENTS_SAVED_FOR_HISTORY", SQLHistoryManager.SAVE_STATEMENTS_MAX_LIMIT_ENTERED);  // NOI18N
246
        }
247
    }
248
249
    private void initComponentData() {
250
        searchTextField.getDocument().addDocumentListener((HistoryTableModel) sqlHistoryTable.getModel());
251
        sqlHistoryTable.getColumnModel().getColumn(0).setHeaderValue(NbBundle.getMessage(SQLHistoryPanel.class, "LBL_SQLTableTitle"));
252
        sqlHistoryTable.getColumnModel().getColumn(1).setHeaderValue(NbBundle.getMessage(SQLHistoryPanel.class, "LBL_DateTableTitle"));
253
        // Add mouse listener to listen for mouse click on the table header so columns can be sorted
254
        JTableHeader header = sqlHistoryTable.getTableHeader();
255
        header.addMouseListener(new ColumnListener());
256
257
        // Add mouse listener for the case when a user double-clicks on a row to insert SQL
258
        sqlHistoryTable.addMouseListener(new MouseAdapter() {
259
            @Override
260
            public void mouseClicked(MouseEvent e) {
156
            public void mouseClicked(MouseEvent e) {
261
                if (MouseUtils.isDoubleClick(e)) {
157
                if (MouseUtils.isDoubleClick(e)) {
262
                    insertSQL();
158
                    insertSQL();
263
                    e.consume();
159
                    e.consume();
160
            }
161
    }
162
        });
163
164
        sqlTableSelektion.addListSelectionListener(
165
                new ListSelectionListener() {
166
167
            @Override
168
                    public void valueChanged(ListSelectionEvent e) {
169
                        if (sqlTableSelektion.isSelectionEmpty()) {
170
                            insertSQLButton.setEnabled(false);
171
                        } else {
172
                            insertSQLButton.setEnabled(true);
173
            }
174
    }
175
                });
176
177
        connectionUrlComboBox.addActionListener(new ActionListener() {
178
179
                @Override
180
            public void actionPerformed(ActionEvent e) {
181
                updateFilter();
182
                }
183
            });
184
        }
185
186
    private void updateFilter() {
187
        List<RowFilter<HistoryTableModel, Integer>> rowFilter = new ArrayList<RowFilter<HistoryTableModel, Integer>>();
188
189
        String url = (String) connectionUrlComboBox.getSelectedItem();
190
191
        if ( url != null && !url.equals(NbBundle.getMessage(SQLHistoryPanel.class, "LBL_URLComboBoxAllConnectionsItem"))) {
192
            rowFilter.add(new EqualsFilter(url, 0));
193
    }
194
195
        if (!searchTextField.getText().equals("")) {
196
            rowFilter.add(new ContainsInsensitiveFilter(searchTextField.getText(), 1));
197
        }
198
199
        if (rowFilter.size() > 0) {
200
            rowSorter.setRowFilter(RowFilter.andFilter(rowFilter));
201
        } else {
202
            rowSorter.setRowFilter(null);
264
                }
203
                }
265
            }
204
            }
266
        });
267
205
268
        // Initialize sql column data
206
    private void updateURLList() {
269
        connectionUrlComboBox.addActionListener((HistoryTableModel) sqlHistoryTable.getModel());
207
        List<String> urls = new ArrayList<String>(htm.getJdbcURLs());
270
        view.updateConnectionUrl();
208
        urls.add(0, NbBundle.getMessage(SQLHistoryPanel.class, "LBL_URLComboBoxAllConnectionsItem"));
271
    }
209
        Object selected = connectionUrlComboBox.getSelectedItem();
272
    
210
        connectionUrlComboBox.setModel(new DefaultComboBoxModel(urls.toArray()));
273
    private void initSQLHistoryTableData() {
211
        if(selected != null && urls.contains(selected)) {
274
        if (initTask == null || ! initTask.isFinished()) {
212
            connectionUrlComboBox.setSelectedItem(selected);
275
            data = new Object[1][2];
213
        } else {
276
            data[0][0] = NbBundle.getMessage(SQLHistoryPanel.class, "SQLHistoryPanel_PleaseWait");
214
            connectionUrlComboBox.setSelectedIndex(0);
277
            return ;
278
        }
279
        // Initialize sql column data          
280
        List<String> sqlList = view.getSQLList(null);
281
        List<String> dateList = view.getDateList(null);
282
        data = new Object[sqlList.size()][2];
283
        int row = 0;
284
        int maxLength; 
285
        int length;
286
        for (String sql : sqlList) {
287
            length = sql.trim().length();
288
            maxLength = length > TABLE_DATA_WIDTH_SQL ? TABLE_DATA_WIDTH_SQL : length;
289
            data[row][0] = sql.trim().substring(0, maxLength).replaceAll("\n", " ");
290
            row++;
291
        }
292
        // Initialize data
293
        row = 0;
294
        for (String date : dateList) {
295
            data[row][1] = date;
296
            row++;
297
        }
215
        }
298
    }
216
    }
299
217
Lines 318-324 Link Here
318
                Component c = super.prepareRenderer(renderer, rowIndex, vColIndex);
236
                Component c = super.prepareRenderer(renderer, rowIndex, vColIndex);
319
                if (c instanceof JComponent) {
237
                if (c instanceof JComponent) {
320
                    JComponent jc = (JComponent)c;
238
                    JComponent jc = (JComponent)c;
321
                    jc.setToolTipText(view.getSQLHistoryTooltipValue(rowIndex, vColIndex));
239
                    jc.setToolTipText(getSQLHistoryTooltipValue(sqlHistoryTable, rowIndex, vColIndex));
322
                }
240
                }
323
                return c;
241
                return c;
324
            }
242
            }
Lines 330-337 Link Here
330
248
331
        jLabel1.setText(org.openide.util.NbBundle.getMessage(SQLHistoryPanel.class, "LBL_Connection")); // NOI18N
249
        jLabel1.setText(org.openide.util.NbBundle.getMessage(SQLHistoryPanel.class, "LBL_Connection")); // NOI18N
332
250
333
        connectionUrlComboBox.setRenderer(new ConnectionUrlRenderer());
334
335
        jLabel2.setLabelFor(searchTextField);
251
        jLabel2.setLabelFor(searchTextField);
336
        org.openide.awt.Mnemonics.setLocalizedText(jLabel2, org.openide.util.NbBundle.getMessage(SQLHistoryPanel.class, "LBL_Match")); // NOI18N
252
        org.openide.awt.Mnemonics.setLocalizedText(jLabel2, org.openide.util.NbBundle.getMessage(SQLHistoryPanel.class, "LBL_Match")); // NOI18N
337
253
Lines 345-360 Link Here
345
            }
261
            }
346
        });
262
        });
347
263
348
        sqlHistoryTable.setModel(new HistoryTableModel());
264
        sqlHistoryTable.setAutoCreateColumnsFromModel(false);
349
        sqlHistoryTable.setGridColor(java.awt.Color.lightGray);
265
        sqlHistoryTable.setModel(htm);
350
        jScrollPane1.setViewportView(sqlHistoryTable);
266
        jScrollPane1.setViewportView(sqlHistoryTable);
351
        sqlHistoryTable.getAccessibleContext().setAccessibleName(org.openide.util.NbBundle.getMessage(SQLHistoryPanel.class, "ACSN_History")); // NOI18N
267
        sqlHistoryTable.getAccessibleContext().setAccessibleName(org.openide.util.NbBundle.getMessage(SQLHistoryPanel.class, "ACSN_History")); // NOI18N
352
        sqlHistoryTable.getAccessibleContext().setAccessibleDescription(org.openide.util.NbBundle.getMessage(SQLHistoryPanel.class, "ACSD_History")); // NOI18N
268
        sqlHistoryTable.getAccessibleContext().setAccessibleDescription(org.openide.util.NbBundle.getMessage(SQLHistoryPanel.class, "ACSD_History")); // NOI18N
269
        int dateColumnWidth1 = new JTextField(dateTimeFormat.format(new Date())).getPreferredSize().width;
270
        int dateColumnWidth2 = new JTextField(NbBundle.getMessage(SQLHistoryPanel.class, "LBL_DateTableTitle") + "XXXXX").getPreferredSize().width;
271
        int dateColumnWidth = Math.max(dateColumnWidth1, dateColumnWidth2);
272
273
        TableColumnModel sqlHistoryTableTCM = sqlHistoryTable.getColumnModel();
274
275
        TableColumn sqlHistoryTableColumn;
276
277
        sqlHistoryTableColumn = new TableColumn(1);
278
        sqlHistoryTableColumn.setHeaderValue(NbBundle.getMessage(SQLHistoryPanel.class, "LBL_SQLTableTitle"));
279
280
        sqlHistoryTableTCM.addColumn(sqlHistoryTableColumn);
281
282
        sqlHistoryTableColumn = new TableColumn(2);
283
        sqlHistoryTableColumn.setMinWidth(dateColumnWidth);
284
        sqlHistoryTableColumn.setPreferredWidth(dateColumnWidth);
285
        sqlHistoryTableColumn.setMaxWidth(dateColumnWidth);
286
        sqlHistoryTableColumn.setHeaderValue(NbBundle.getMessage(SQLHistoryPanel.class, "LBL_DateTableTitle"));
287
        sqlHistoryTableColumn.setCellRenderer(new DefaultTableCellRenderer() {
288
            public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
289
                if(value instanceof Date) {
290
                    value = dateTimeFormat.format((Date) value);
291
                }
292
                return super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
293
            }
294
        });
295
296
        sqlHistoryTableTCM.addColumn(sqlHistoryTableColumn);
353
297
354
        sqlLimitLabel.setLabelFor(sqlLimitTextField);
298
        sqlLimitLabel.setLabelFor(sqlLimitTextField);
355
        org.openide.awt.Mnemonics.setLocalizedText(sqlLimitLabel, org.openide.util.NbBundle.getMessage(SQLHistoryPanel.class, "LBL_SqlLimit")); // NOI18N
299
        org.openide.awt.Mnemonics.setLocalizedText(sqlLimitLabel, org.openide.util.NbBundle.getMessage(SQLHistoryPanel.class, "LBL_SqlLimit")); // NOI18N
356
300
357
        sqlLimitTextField.setText(SQLHistoryManager.SAVE_STATEMENTS_MAX_LIMIT_ENTERED);
301
        sqlLimitTextField.setText(Integer.toString(SQLHistoryManager.getInstance().getListSize()));
358
        sqlLimitTextField.setMinimumSize(new java.awt.Dimension(18, 22));
302
        sqlLimitTextField.setMinimumSize(new java.awt.Dimension(18, 22));
359
303
360
        org.openide.awt.Mnemonics.setLocalizedText(sqlLimitButton, org.openide.util.NbBundle.getMessage(SQLHistoryPanel.class, "LBL_ApplyButton")); // NOI18N
304
        org.openide.awt.Mnemonics.setLocalizedText(sqlLimitButton, org.openide.util.NbBundle.getMessage(SQLHistoryPanel.class, "LBL_ApplyButton")); // NOI18N
Lines 378-388 Link Here
378
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
322
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
379
                    .addGroup(layout.createSequentialGroup()
323
                    .addGroup(layout.createSequentialGroup()
380
                        .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
324
                        .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
381
                            .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 655, Short.MAX_VALUE)
325
                            .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 645, Short.MAX_VALUE)
382
                            .addGroup(layout.createSequentialGroup()
326
                            .addGroup(layout.createSequentialGroup()
383
                                .addComponent(jLabel1)
327
                                .addComponent(jLabel1)
384
                                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
328
                                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
385
                                .addComponent(connectionUrlComboBox, 0, 306, Short.MAX_VALUE)
329
                                .addComponent(connectionUrlComboBox, 0, 301, Short.MAX_VALUE)
386
                                .addGap(18, 18, 18)
330
                                .addGap(18, 18, 18)
387
                                .addComponent(jLabel2)
331
                                .addComponent(jLabel2)
388
                                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
332
                                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
Lines 413-419 Link Here
413
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
357
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
414
                    .addComponent(insertSQLButton)
358
                    .addComponent(insertSQLButton)
415
                    .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
359
                    .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
416
                        .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 168, Short.MAX_VALUE)
360
                        .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 268, Short.MAX_VALUE)
417
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
361
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
418
                        .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
362
                        .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
419
                            .addComponent(sqlLimitTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
363
                            .addComponent(sqlLimitTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
Lines 432-437 Link Here
432
        insertSQLButton.getAccessibleContext().setAccessibleDescription(org.openide.util.NbBundle.getMessage(SQLHistoryPanel.class, "ACSD_Insert")); // NOI18N
376
        insertSQLButton.getAccessibleContext().setAccessibleDescription(org.openide.util.NbBundle.getMessage(SQLHistoryPanel.class, "ACSD_Insert")); // NOI18N
433
        sqlLimitTextField.getAccessibleContext().setAccessibleName(org.openide.util.NbBundle.getMessage(SQLHistoryPanel.class, "ACSN_Save")); // NOI18N
377
        sqlLimitTextField.getAccessibleContext().setAccessibleName(org.openide.util.NbBundle.getMessage(SQLHistoryPanel.class, "ACSN_Save")); // NOI18N
434
        sqlLimitTextField.getAccessibleContext().setAccessibleDescription(org.openide.util.NbBundle.getMessage(SQLHistoryPanel.class, "ACSD_Save")); // NOI18N
378
        sqlLimitTextField.getAccessibleContext().setAccessibleDescription(org.openide.util.NbBundle.getMessage(SQLHistoryPanel.class, "ACSD_Save")); // NOI18N
379
        sqlLimitTextField.setInputVerifier(new InputVerifier() {
380
381
            public boolean verify(JComponent input) {
382
                JTextField tf = (JTextField) input;
383
                return tf.getText().matches("^\\d+$");
384
            }
385
        });
435
        sqlLimitButton.getAccessibleContext().setAccessibleName(org.openide.util.NbBundle.getMessage(SQLHistoryPanel.class, "ACSN_Apply")); // NOI18N
386
        sqlLimitButton.getAccessibleContext().setAccessibleName(org.openide.util.NbBundle.getMessage(SQLHistoryPanel.class, "ACSN_Apply")); // NOI18N
436
        sqlLimitButton.getAccessibleContext().setAccessibleDescription(org.openide.util.NbBundle.getMessage(SQLHistoryPanel.class, "ACSD_Apply")); // NOI18N
387
        sqlLimitButton.getAccessibleContext().setAccessibleDescription(org.openide.util.NbBundle.getMessage(SQLHistoryPanel.class, "ACSD_Apply")); // NOI18N
437
    }// </editor-fold>//GEN-END:initComponents
388
    }// </editor-fold>//GEN-END:initComponents
Lines 444-565 Link Here
444
    verifySQLLimit();
395
    verifySQLLimit();
445
}//GEN-LAST:event_sqlLimitButtonActionPerformed
396
}//GEN-LAST:event_sqlLimitButtonActionPerformed
446
397
447
448
    private void insertSQL() {
398
    private void insertSQL() {
449
        try {
399
        try {
450
            // Make sure to insert the entire SQL, not just what appears in the Table
400
            JEditorPane pane = (JEditorPane) EditorRegistry.lastFocusedComponent();
451
            List<SQLHistory> sqlHistoryList = view.getCurrentSQLHistoryList();
452
            int i = 0;
453
            String sqlToInsert = ""; // NOI18N
454
            InsertSQLUtility insertUtility = new InsertSQLUtility();
455
            for (SQLHistory sqlHistory : sqlHistoryList) {
456
                if (sqlHistoryTable.isRowSelected(i)) {
457
                    sqlToInsert = sqlHistory.getSql().trim();
458
                    JEditorPane pane = (JEditorPane)EditorRegistry.lastFocusedComponent();
459
                    String mime = pane.getContentType();
401
                    String mime = pane.getContentType();
460
                    if (mime.equals(SQLDataLoader.SQL_MIME_TYPE)) {
402
                    if (mime.equals(SQLDataLoader.SQL_MIME_TYPE)) {
461
                        editorPane = pane;
403
                        editorPane = pane;
462
                    }
404
                    }
463
                    insertUtility.insert(sqlToInsert, editorPane);
405
            int min = sqlTableSelektion.getMinSelectionIndex();
406
            int max = sqlTableSelektion.getMaxSelectionIndex();
407
            for (int i = min; i <= max; i++) {
408
                if (sqlHistoryTable.isRowSelected(i)) {
409
                    int modelIndex = sqlHistoryTable.convertRowIndexToModel(i);
410
                    String sql = ((String) htm.getValueAt(modelIndex, 1)).trim();
411
                    insertIntoDocument(sql, editorPane);
464
                }
412
                }
465
                // increment for the next row
466
                i++;
467
            }
413
            }
468
            
469
        } catch (BadLocationException ex) {
414
        } catch (BadLocationException ex) {
470
            Exceptions.printStackTrace(ex);
415
            Exceptions.printStackTrace(ex);
471
        }
416
        }
472
    }
417
    }
473
418
474
    private void verifySQLLimit() {
419
    private void verifySQLLimit() {
475
        String enteredLimit = sqlLimitTextField.getText();
420
        String enteredLimitString = sqlLimitTextField.getText();
476
        int iLimit = 0;
421
        String currentLimit = Integer.toString(SQLHistoryManager.getInstance().getListSize());
477
        if (enteredLimit.equals(SAVE_STATEMENTS_CLEARED)) {
422
        String maxLimit = Integer.toString(SQLHistoryManager.MAX_SQL_STATEMENTS_SAVED_FOR_HISTORY);
478
            updateSaveLimitUponClear(iLimit);
423
        if (enteredLimitString.equals(SAVE_STATEMENTS_CLEARED)) {
479
            inputWarningLabel.setText(""); // NOI18N
424
            sqlLimitTextField.setText(currentLimit);
480
        } else { // user enters a value to limit the number of SQL statements to save
425
            return;
481
            updateSaveLimitUponReset(enteredLimit);
426
    }
427
        try {
428
            Integer enteredLimit = Integer.valueOf(enteredLimitString);
429
            if (enteredLimit > SQLHistoryManager.MAX_SQL_STATEMENTS_SAVED_FOR_HISTORY) {
430
                inputWarningLabel.setText(NbBundle.getMessage(SQLHistoryPanel.class, "LBL_NumberInputWarningLabel"));
431
                sqlLimitTextField.setText(maxLimit);
432
                SQLHistoryManager.getInstance().setListSize(SQLHistoryManager.MAX_SQL_STATEMENTS_SAVED_FOR_HISTORY);
433
                } else {
434
                inputWarningLabel.setText(""); // NOI18N
435
                SQLHistoryManager.getInstance().setListSize(enteredLimit);
436
                }
437
        } catch (NumberFormatException ex) {
438
                inputWarningLabel.setText(NbBundle.getMessage(SQLHistoryPanel.class, "LBL_NumberInputWarningLabel"));
439
            sqlLimitTextField.setText(currentLimit);
482
        }
440
        }
483
    }
441
        htm.refresh();
442
                }
484
443
485
    private void updateSaveLimitUponClear(int iLimit) {
444
    public String getSQLHistoryTooltipValue(JTable historyTable, int row, int col) {
486
        iLimit = SAVE_STATEMENTS_MAX_LIMIT;
445
        HistoryTableModel historyTableModel = (HistoryTableModel) historyTable.getModel();
487
        List<SQLHistory> sqlHistoryList = new ArrayList<SQLHistory>();
446
        int modelColumn = historyTable.convertColumnIndexToModel(col);
488
        try {
447
        int modelRow = historyTable.convertRowIndexToModel(row);
489
            view.setSQLHistoryList(SQLHistoryPersistenceManager.getInstance().updateSQLSaved(iLimit, historyRoot));
448
490
            sqlHistoryList = SQLHistoryPersistenceManager.getInstance().retrieve(historyRoot);
449
        if (String.class.isAssignableFrom(historyTableModel.getColumnClass(modelColumn))) {
491
            view.setCurrentSQLHistoryList(sqlHistoryList);
450
            String data = (String) historyTableModel.getValueAt(modelRow, modelColumn);
492
        } catch (ClassNotFoundException ex) {
451
            return "<html>" + data.trim().replace("\n", "<br>") + "</html>";       // NOI18N
493
            Exceptions.printStackTrace(ex);
452
        } else if (Date.class.isAssignableFrom(historyTableModel.getColumnClass(modelColumn))) {
494
        } catch (SQLHistoryException ex) {
453
            Date data = (Date) historyTableModel.getValueAt(modelRow, modelColumn);
495
            handleSQLHistoryException();
454
            return DateFormat.getInstance().format(data);
496
        }
497
        ((HistoryTableModel) sqlHistoryTable.getModel()).refreshTable(sqlHistoryList);
498
        NbPreferences.forModule(SQLHistoryPanel.class).put("SQL_STATEMENTS_SAVED_FOR_HISTORY", Integer.toString(iLimit));  // NOI18N               
499
        sqlLimitTextField.setText(SQLHistoryManager.SAVE_STATEMENTS_MAX_LIMIT_ENTERED);
500
    }
501
    
502
    private void updateSaveLimitUponReset(String enteredLimit) {
503
        try {
504
            int iLimit;
505
            if (enteredLimit.trim().length() < 10) {
506
                iLimit = Integer.parseInt(enteredLimit);
507
            } else {
455
            } else {
508
                // too long number
456
            return null;
509
                iLimit = SAVE_STATEMENTS_MAX_LIMIT + 1;
510
            }
511
            String savedLimit = NbPreferences.forModule(SQLHistoryPanel.class).get("SQL_STATEMENTS_SAVED_FOR_HISTORY", SAVE_STATEMENTS_CLEARED); // NOI18N
512
            if (iLimit < 0) {
513
                inputWarningLabel.setText(NbBundle.getMessage(SQLHistoryPanel.class, "LBL_TextInputWarningLabel"));
514
                if (savedLimit != null) {
515
                    sqlLimitTextField.setText(savedLimit);
516
                } else {
517
                    sqlLimitTextField.setText(SQLHistoryManager.SAVE_STATEMENTS_MAX_LIMIT_ENTERED); 
518
                }
519
            } else if (iLimit > SAVE_STATEMENTS_MAX_LIMIT) {
520
                sqlLimitButton.setEnabled(true);
521
                inputWarningLabel.setText(NbBundle.getMessage(SQLHistoryPanel.class, "LBL_NumberInputWarningLabel"));
522
                // reset user's input
523
                if (savedLimit != null) {
524
                    sqlLimitTextField.setText(savedLimit);
525
                } else {
526
                    sqlLimitTextField.setText(SAVE_STATEMENTS_CLEARED); 
527
                    sqlLimitTextField.setText(SQLHistoryManager.SAVE_STATEMENTS_MAX_LIMIT_ENTERED); 
528
                }
529
            } else {
530
                inputWarningLabel.setText(""); // NOI18N
531
                if (SQLHistoryPersistenceManager.getInstance().updateSQLSaved(iLimit, historyRoot).size() > 0) {
532
                    List<SQLHistory> sqlHistoryList = SQLHistoryPersistenceManager.getInstance().retrieve(historyRoot);
533
                    view.setCurrentSQLHistoryList(sqlHistoryList);
534
                    ((HistoryTableModel) sqlHistoryTable.getModel()).refreshTable(sqlHistoryList);
535
                    view.updateConnectionUrl();
536
                    NbPreferences.forModule(SQLHistoryPanel.class).put("SQL_STATEMENTS_SAVED_FOR_HISTORY", Integer.toString(iLimit));  // NOI18N
537
                }
457
                }
538
            }
458
            }
539
        } catch (ClassNotFoundException ex) {
459
540
            Exceptions.printStackTrace(ex);
460
    private int insertIntoDocument(String s, JEditorPane target)
541
        } catch (SQLHistoryException ex) {
461
            throws BadLocationException {
542
            handleSQLHistoryException();
462
        Document doc = target.getDocument();
543
        } catch (NumberFormatException ne) {
463
        if (s == null) {
544
            inputWarningLabel.setText(NbBundle.getMessage(SQLHistoryPanel.class, "LBL_TextInputWarningLabel"));
464
            s = "";
545
            // reset user's input
546
            String savedLimit = NbPreferences.forModule(SQLHistoryPanel.class).get("SQL_STATEMENTS_SAVED_FOR_HISTORY", ""); // NOI18N
547
            if (savedLimit != null) {
548
                sqlLimitTextField.setText(savedLimit);
549
            } else {
550
                sqlLimitTextField.setText(SQLHistoryManager.SAVE_STATEMENTS_MAX_LIMIT_ENTERED); 
551
            }
465
            }
466
        if (doc == null) {
467
            return -1;
552
        }        
468
        }        
469
        int start = -1;
470
        try {
471
            Caret caret = target.getCaret();
472
            int p0 = Math.min(caret.getDot(), caret.getMark());
473
            int p1 = Math.max(caret.getDot(), caret.getMark());
474
            doc.remove(p0, p1 - p0);
475
            start = caret.getDot();
476
            doc.insertString(start, s + ";\n", null); // NOI18N
477
        } catch (BadLocationException ble) {
478
            LOGGER.log(Level.WARNING, org.openide.util.NbBundle.getMessage(SQLHistoryPanel.class, "LBL_InsertAtLocationError") + ble);
553
    }
479
    }
554
    
480
        return start;
555
    private void handleSQLHistoryException() {
556
        LOGGER.log(Level.WARNING, NbBundle.getMessage(SQLHistoryPanel.class, "LBL_ErrorParsingSQLHistory"));
557
        List<SQLHistory> sqlHistoryList = SQLHistoryPersistenceManager.getInstance().retrieve();
558
        view.setCurrentSQLHistoryList(sqlHistoryList);
559
        ((HistoryTableModel) sqlHistoryTable.getModel()).refreshTable(sqlHistoryList);
560
        view.updateConnectionUrl();
561
    }
481
    }
562
563
    // Variables declaration - do not modify//GEN-BEGIN:variables
482
    // Variables declaration - do not modify//GEN-BEGIN:variables
564
    private javax.swing.JComboBox connectionUrlComboBox;
483
    private javax.swing.JComboBox connectionUrlComboBox;
565
    private javax.swing.JLabel inputWarningLabel;
484
    private javax.swing.JLabel inputWarningLabel;
Lines 574-773 Link Here
574
    private javax.swing.JTextField sqlLimitTextField;
493
    private javax.swing.JTextField sqlLimitTextField;
575
    // End of variables declaration//GEN-END:variables
494
    // End of variables declaration//GEN-END:variables
576
495
577
    private class SQLHistoryView {
496
    private final class HistoryTableModel extends AbstractTableModel {
578
        private SQLHistoryModel model;
579
        List<SQLHistory> sqlHistoryList = new ArrayList<SQLHistory>();
580
        List<SQLHistory> currentSQLHistoryList  = new ArrayList<SQLHistory>();
581
        public static final String MATCH_EMPTY = ""; // NOI18N
582
583
        public SQLHistoryView(SQLHistoryModel model) {
584
            this.model = model;
585
            init();
586
        }
587
        
497
        
588
        private void init() {
498
        private List<SQLHistoryEntry> sqlList;
589
            try {
499
        private List<String> jdbcURLs = new ArrayList<String>();
590
                this.sqlHistoryList = model.getSQLHistoryList();
500
        private SQLHistoryManager shm = SQLHistoryManager.getInstance();
591
                this.currentSQLHistoryList = model.getSQLHistoryList();
592
            } catch (SQLHistoryException ex) {
593
                LOGGER.log(Level.INFO, NbBundle.getMessage(SQLHistoryPanel.class, "LBL_ErrorParsingSQLHistory"), ex); // NOI18N
594
                sqlHistoryList = SQLHistoryPersistenceManager.getInstance().retrieve();
595
                setCurrentSQLHistoryList(sqlHistoryList);
596
            }
597
        }
598
599
        public void setCurrentSQLHistoryList(List<SQLHistory> sqlHistoryList) {
600
            currentSQLHistoryList = sqlHistoryList;
601
        }
602
603
        public List<SQLHistory> getCurrentSQLHistoryList() {
604
            return currentSQLHistoryList;
605
        }
606
607
        public List<SQLHistory> getSQLHistoryList() {
608
            return sqlHistoryList;
609
        }
610
        
611
        public void setSQLHistoryList(List<SQLHistory> sqlHistoryList) {
612
             this.sqlHistoryList = sqlHistoryList;
613
        }
614
        
615
        /**
616
         * Get the SQL statement string at the row,col position in the table and convert the string to html
617
         * @param row - table row
618
         * @param col - table column
619
         * @return    - formatted SQL statement for the specified row, col
620
         */
621
        public String getSQLHistoryTooltipValue(int row, int col) {
622
            List<SQLHistory> sqlHistoryListForTooltip =  view.getCurrentSQLHistoryList();
623
            if (sqlHistoryListForTooltip != null && row < sqlHistoryListForTooltip.size()) {
624
                if (col == 0) {
625
                    String sqlRow = sqlHistoryListForTooltip.get(row).getSql().trim();
626
                    while (sqlRow.indexOf("\n") != -1) {        // NOI18N
627
                        sqlRow = replace(sqlRow, "\n", "<br>"); // NOI18N
628
                    }
629
                    return "<html>" + sqlRow + "</html>";       // NOI18N
630
                } else {
631
                    return DateFormat.getInstance().format(sqlHistoryListForTooltip.get(row).getDate());
632
                }
633
            } else {
634
                return null;
635
            }
636
        }
637
        
638
        /**
639
         * Convert sql statement to html for proper rendering in the table's tooltip
640
         * @param target - original string
641
         * @param from - string to replace
642
         * @param to - string to replace with
643
         * @return - updated string
644
         */
645
        public String replace(String target, String from, String to) {
646
            int start = target.indexOf(from);
647
            if (start == -1) {
648
                return target;
649
            }
650
            int lf = from.length();
651
            char[] targetChars = target.toCharArray();
652
            StringBuilder buffer = new StringBuilder();
653
            int copyFrom = 0;
654
            while (start != -1) {
655
                buffer.append(targetChars, copyFrom, start - copyFrom);
656
                buffer.append(to);
657
                copyFrom = start + lf;
658
                start = target.indexOf(from, copyFrom);
659
            }
660
            buffer.append(targetChars, copyFrom, targetChars.length - copyFrom);
661
            return buffer.toString();
662
        }
663
             
501
             
664
        public List<String> getSQLList(List<SQLHistory> sqlHistoryList) {
502
        public HistoryTableModel() {
665
            List<String> sqlList = new ArrayList<String>();
503
            refresh();
666
            if (sqlHistoryList == null) {
667
                sqlHistoryList = getSQLHistoryList();
668
            }
504
            }
669
505
670
            for (SQLHistory sqlHistory : sqlHistoryList) {
506
        public void refresh() {
671
                String sql = sqlHistory.getSql();
507
            sqlList = new ArrayList<SQLHistoryEntry>(shm.getSQLHistory());
672
                if (!sqlList.contains(sql)) {
508
            for (SQLHistoryEntry sqe : sqlList) {
673
                    sqlList.add(sql); 
509
                String url = sqe.getUrl();
510
                if (!jdbcURLs.contains(url)) {
511
                    jdbcURLs.add(url);
674
                }
512
                }
675
            }
513
            }
676
            return sqlList;
514
            fireTableDataChanged();
677
        }
515
        }
678
516
679
        public List<String> getDateList(List<SQLHistory> sqlHistoryList) {
680
            List<String> dateList = new ArrayList<String>();
681
            List<String> sqlList = new ArrayList<String>();
682
            if (sqlHistoryList == null) {
683
                sqlHistoryList = getSQLHistoryList();
684
            }
685
686
            for (SQLHistory sqlHistory : sqlHistoryList) {
687
                String date = DateFormat.getInstance().format(sqlHistory.getDate());
688
                String sql = sqlHistory.getSql();
689
                // need to make sure that the date is the one that belongs with the SQL
690
                if (!sqlList.contains(sql)) {                                        
691
                    sqlList.add(sql); 
692
                    dateList.add(date);
693
                }
694
            }
695
            return dateList;
696
        }
697
698
        public void updateConnectionUrl() {
699
            // Initialize combo box data
700
            currentConnections.clear();
701
            // Set default item in the combo box
702
            String defaultSelectedItem = NbBundle.getMessage(SQLHistoryPanel.class, "LBL_URLComboBoxAllConnectionsItem");
703
            currentConnections.add(defaultSelectedItem);
704
705
            for (SQLHistory sqlHistory : sqlHistoryList) {
706
                String url = sqlHistory.getUrl();
707
                if (urlAliasMap.containsKey(url)) {
708
                    // add connection display name
709
                    currentConnections.add(urlAliasMap.get(url));
710
                } else {
711
                    // add URL
712
                    currentConnections.add(url);
713
                }
714
            }
715
            // Initialize combo box
716
            connectionUrlComboBox.setModel(new DefaultComboBoxModel(currentConnections.toArray()));
717
            connectionUrlComboBox.setSelectedItem(defaultSelectedItem);
718
            connectionUrlComboBox.revalidate();
719
        }
720
721
        private List<SQLHistory> filterSQLHistoryList() {
722
            List<SQLHistory> filteredSqlHistoryList = new ArrayList<SQLHistory>();
723
            String match = searchTextField.getText();
724
            String url = (String)connectionUrlComboBox.getSelectedItem();
725
            if (aliasUrlMap.containsKey(url)) {
726
                url = aliasUrlMap.get(url);
727
            }
728
            // modify list of SQL to reflect a selection from the Connection dropdown or if a match text entered
729
            for (SQLHistory sqlHistory : sqlHistoryList) {
730
                if (sqlHistory.getUrl().equals(url) || url.equals(NbBundle.getMessage(SQLHistoryPanel.class, "LBL_URLComboBoxAllConnectionsItem"))) {
731
                    if (!match.equals(MATCH_EMPTY)) {
732
                        if (sqlHistory.getSql().toLowerCase().indexOf(match.toLowerCase()) != -1) {
733
                            filteredSqlHistoryList.add(sqlHistory);
734
                        }
735
                    } else {
736
                        filteredSqlHistoryList.add(sqlHistory);
737
                    }
738
                }
739
            }
740
            currentSQLHistoryList = filteredSqlHistoryList;
741
            return filteredSqlHistoryList;
742
        }
743
    }
744
745
    private final class HistoryTableModel extends DefaultTableModel implements ActionListener, DocumentListener {
746
        List<String> sqlList;
747
        List<String> dateList;
748
        int sortCol = 1;
749
        boolean sortAsc = false;
750
751
        @Override
517
        @Override
752
        public int getRowCount() {
518
        public int getRowCount() {
753
            if (sqlHistoryTable.getSelectedRow() == -1) {
519
            return sqlList.size();
754
                insertSQLButton.setEnabled(false);
755
            } 
756
            return data.length;
757
        }
520
        }
758
521
759
        @Override
522
        @Override
760
        public int getColumnCount() {
523
        public int getColumnCount() {
761
            return 2;
524
            return 4;
762
        }
525
        }
763
526
764
        @Override
527
        @Override
765
        public Class<?> getColumnClass(int c) {
528
        public Class<?> getColumnClass(int c) {
766
            Object value = getValueAt(0, c);
529
            switch (c) {
767
            if (value == null) {
530
                case 0:
768
                return String.class;
531
                return String.class;
769
            } else {
532
                case 1:
770
                return getValueAt(0, c).getClass();
533
                    return String.class;
534
                case 2:
535
                    return Date.class;
536
                case 3:
537
                    return SQLHistoryEntry.class;
538
                default:
539
                    return Object.class;
771
            }
540
            }
772
        }
541
        }
773
542
Lines 778-1127 Link Here
778
547
779
        @Override
548
        @Override
780
        public Object getValueAt(int row, int col) {
549
        public Object getValueAt(int row, int col) {
781
            if (sqlHistoryTable.isRowSelected(row)) {
550
            switch (col) {
782
                insertSQLButton.setEnabled(true);
551
                case 0:
552
                    return sqlList.get(row).getUrl();
553
                case 1:
554
                    return sqlList.get(row).getSql();
555
                case 2:
556
                    return sqlList.get(row).getDate();
557
                case 3:
558
                    return sqlList.get(row);
559
                default:
560
                    return null;
783
            } 
561
            } 
784
            return data[row][col];
785
        }
562
        }
786
563
787
        @Override
564
        @Override
788
        public void setValueAt(Object value, int row, int col) {
565
        public void setValueAt(Object value, int row, int col) {
789
            adjustColumnPreferredWidths(sqlHistoryTable);
566
            throw new NotImplementedException();
790
            fireTableCellUpdated(row, col);
567
    }
568
569
        public List<String> getJdbcURLs() {
570
            return jdbcURLs;
571
        }
572
        }
573
574
    private class EqualsFilter extends RowFilter<HistoryTableModel, Integer> {
575
576
        private String referenz;
577
        private int referenzColumn;
578
579
        public EqualsFilter(String referenz, int referenzColumn) {
580
            this.referenz = referenz;
581
            this.referenzColumn = referenzColumn;
582
        }
583
584
            @Override
585
        public boolean include(Entry<? extends HistoryTableModel, ? extends Integer> entry) {
586
            return ((String) entry.getModel().getValueAt(entry.getIdentifier(), referenzColumn)).equals(referenz);
587
            }
588
        };
589
590
    private class ContainsInsensitiveFilter extends RowFilter<HistoryTableModel, Integer> {
591
592
        private String referenz;
593
        private int referenzColumn;
594
595
        public ContainsInsensitiveFilter(String referenz, int referenzColumn) {
596
            this.referenz = referenz.toLowerCase();
597
            this.referenzColumn = referenzColumn;
791
        }
598
        }
792
599
793
        @Override
600
        @Override
794
        public void addTableModelListener(TableModelListener arg0) {
601
        public boolean include(Entry<? extends HistoryTableModel, ? extends Integer> entry) {
795
            // not used
602
            return ((String) entry.getModel().getValueAt(entry.getIdentifier(), referenzColumn)).toLowerCase().contains(referenz);
796
        }
797
798
        @Override
799
        public void removeTableModelListener(TableModelListener arg0) {
800
            // not used
801
        }
802
803
        public void adjustColumnPreferredWidths(JTable table) {
804
            // Get max width for cells in column and make that the preferred width
805
            TableColumnModel columnModel = table.getColumnModel();
806
            for (int col = 0; col < table.getColumnCount(); col++) {
807
808
                int maxwidth = 0;
809
                for (int row = 0; row < table.getRowCount(); row++) {
810
                    TableCellRenderer rend =
811
                            table.getCellRenderer(row, col);
812
                    Object value = table.getValueAt(row, col);
813
                    Component comp =
814
                            rend.getTableCellRendererComponent(table,
815
                            value,
816
                            false,
817
                            false,
818
                            row,
819
                            col);
820
                    maxwidth = Math.max(comp.getPreferredSize().width, maxwidth);
821
                }
822
                TableColumn column = columnModel.getColumn(col);
823
                column.setPreferredWidth(maxwidth);
824
                column.setHeaderRenderer(createDefaultRenderer());
825
            }
826
        }
827
828
        @Override
829
        public void actionPerformed(ActionEvent evt) {
830
            processUpdate();
831
        }
832
        
833
        public void refreshTable(List<SQLHistory> sqlHistoryList) {
834
            if (initTask == null) {
835
                return ;
836
            }
837
            String url;
838
            // Get the connection url from the combo box
839
            if (sqlHistoryList.size() > 0) {
840
                url = connectionUrlComboBox.getSelectedItem().toString();
841
                if (aliasUrlMap.containsKey(url)) {
842
                    url = aliasUrlMap.get(url);
843
                }
844
            } else {
845
                url = NbBundle.getMessage(SQLHistoryPanel.class, "LBL_URLComboBoxAllConnectionsItem");
846
            }
847
            sqlList = new ArrayList<String>();
848
            dateList = new ArrayList<String>();
849
            connectionUrlComboBox.setToolTipText(url);
850
            int length;
851
            int maxLength;
852
            for (SQLHistory sqlHistory : sqlHistoryList) {
853
                if (url.equals(NbBundle.getMessage(SQLHistoryPanel.class, "LBL_URLComboBoxAllConnectionsItem")) ||
854
                      url.equals(sqlHistory.getUrl())) {
855
                    length = sqlHistory.getSql().trim().length();
856
                    maxLength = length > TABLE_DATA_WIDTH_SQL ? TABLE_DATA_WIDTH_SQL : length;
857
                    sqlList.add(sqlHistory.getSql().trim().substring(0, maxLength).replaceAll("\n", " "));
858
                    dateList.add(DateFormat.getInstance().format(sqlHistory.getDate()));
859
                }
860
            }
861
            // Initialize sql column data
862
            data = null;
863
            data = new Object[sqlList.size()][2];
864
            int row = 0;
865
            for (String sql : sqlList) {
866
                length = sql.trim().length();
867
                maxLength = length > TABLE_DATA_WIDTH_SQL ? TABLE_DATA_WIDTH_SQL : length;
868
                data[row][0] = sql.trim().substring(0, maxLength).replaceAll("\n", " ");
869
                row++;
870
            }
871
            // Initialize date column data
872
            row = 0;
873
            for (String date : dateList) {
874
                data[row++][1] = date;
875
            }
876
            // Refresh table
877
            if (data.length > 0) {
878
                sqlHistoryTable.revalidate();
879
            } else {
880
                sqlHistoryTable.revalidate();
881
                insertSQLButton.setEnabled(false);
882
            }
883
        }
884
885
        @Override
886
        public void insertUpdate(DocumentEvent evt) {
887
            processUpdate();
888
                    } 
889
890
        @Override
891
        public void removeUpdate(DocumentEvent evt) {
892
            processUpdate();
893
                    }
894
895
        private void processUpdate() {
896
            view.setCurrentSQLHistoryList(view.filterSQLHistoryList());
897
            sqlHistoryTable.repaint();
898
            sqlHistoryTable.clearSelection();
899
            refreshTable(view.getCurrentSQLHistoryList());
900
                    }
901
902
        @Override
903
        public void changedUpdate(DocumentEvent arg0) {
904
            // unused
905
        }
906
907
        public List<SQLHistory> sortData() {
908
            // Refresh the table
909
            List<SQLHistory> filteredSQLHistoryList = view.filterSQLHistoryList();
910
            SQLComparator sqlComparator = new SQLComparator(sortCol, sortAsc);
911
            Collections.sort(filteredSQLHistoryList, sqlComparator);
912
            view.setCurrentSQLHistoryList(filteredSQLHistoryList);
913
            refreshTable( filteredSQLHistoryList);
914
            return filteredSQLHistoryList;
915
        }
916
    }
603
    }
917
604
    };
918
    public static String read(Document doc) throws InterruptedException, Exception {
919
        Renderer r = new Renderer(doc);
920
        doc.render(r);
921
922
        synchronized (r) {
923
            while (!r.done) {
924
                r.wait();
925
                if (r.err != null) {
926
                    throw new Exception(r.err);
927
                }
928
            }
929
        }
930
        return r.result;
931
    }
932
933
    private static class Renderer implements Runnable {
934
        Document doc;
935
        String result;
936
        Throwable err;
937
        boolean done;
938
939
        Renderer(Document doc) {
940
            this.doc = doc;
941
        }
942
943
        @Override
944
        public synchronized void run() {
945
            try {
946
                result = doc.getText(0, doc.getLength());
947
            } catch (Throwable e) {
948
                err = e;
949
                Exceptions.printStackTrace(e);
950
            }
951
            done = true;
952
            notify();
953
        }
954
    }
955
956
    private class InsertSQLUtility {
957
958
        public InsertSQLUtility() {
959
        }
960
961
        public void insert(String s, JEditorPane target)
962
                throws BadLocationException {
963
            insert(s, target, false);
964
        }
965
966
        public void insert(String s, JEditorPane target, boolean reformat)
967
                throws BadLocationException {
968
969
            if (s == null) {
970
                s = "";  // NOI18N
971
            }
972
973
            Document doc = target.getDocument();
974
            if (doc != null) {
975
                insert(s, target, doc);
976
            }
977
        }
978
979
        private int insert(String s, JEditorPane target, Document doc)
980
                throws BadLocationException {
981
982
            int start = -1;
983
            try {
984
                Caret caret = target.getCaret();
985
                int p0 = Math.min(caret.getDot(), caret.getMark());
986
                int p1 = Math.max(caret.getDot(), caret.getMark());
987
                doc.remove(p0, p1 - p0);
988
                start = caret.getDot();
989
                doc.insertString(start, s + ";\n", null); // NOI18N
990
            } catch (BadLocationException ble) {
991
                LOGGER.log(Level.WARNING, org.openide.util.NbBundle.getMessage(SQLHistoryPanel.class, "LBL_InsertAtLocationError") + ble);
992
            }
993
            return start;
994
        }
995
    }
996
997
    private static void adjustColumnPreferredWidths(JTable table) {
998
        TableColumnModel columnModel = table.getColumnModel();
999
        for (int col = 0; col < table.getColumnCount(); col++) {
1000
1001
            int maxwidth = 0;
1002
            for (int row = 0; row < table.getRowCount(); row++) {
1003
                TableCellRenderer rend =
1004
                        table.getCellRenderer(row, col);
1005
                Object value = table.getValueAt(row, col);
1006
                Component comp =
1007
                        rend.getTableCellRendererComponent(table,
1008
                        value,
1009
                        false,
1010
                        false,
1011
                        row,
1012
                        col);
1013
                maxwidth = Math.max(comp.getPreferredSize().width, maxwidth);
1014
            }
1015
            TableColumn column = columnModel.getColumn(col);
1016
            column.setPreferredWidth(maxwidth);
1017
        }
1018
    }
1019
1020
    private static final class ConnectionUrlRenderer extends DefaultListCellRenderer {
1021
1022
        @Override
1023
        public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
1024
            JLabel component = (JLabel) super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
1025
            component.setToolTipText((String) value);
1026
            return component;
1027
        }
1028
    }
1029
1030
    private TableCellRenderer createDefaultRenderer() {
1031
        DefaultTableCellRenderer label = new DefaultTableCellRenderer() {
1032
1033
            @Override
1034
            public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
1035
                if (table != null) {
1036
                    JTableHeader header = table.getTableHeader();
1037
                    if (header != null) {
1038
                        setForeground(header.getForeground());
1039
                        setBackground(header.getBackground());
1040
                        setFont(header.getFont());
1041
                    }
1042
                }
1043
                setText((value == null) ? "" : value.toString());
1044
                setBorder(UIManager.getBorder("TableHeader.cellBorder"));
1045
                return SQLHistoryPanel.this;
1046
            }
1047
        };
1048
        label.setHorizontalAlignment(JLabel.CENTER);
1049
        return label;
1050
    }
1051
1052
    private class ColumnListener extends MouseAdapter {
1053
        @Override
1054
        public void mouseClicked(MouseEvent e) {
1055
            HistoryTableModel model = (HistoryTableModel)sqlHistoryTable.getModel();
1056
            TableColumnModel colModel = sqlHistoryTable.getColumnModel();
1057
            int colModelIndex = colModel.getColumnIndexAtX(e.getX());
1058
            int modelIndex = colModel.getColumn(colModelIndex).getModelIndex();
1059
            if (modelIndex < 0) {
1060
                return;
1061
            }
1062
            if (model.sortCol == modelIndex) {
1063
                model.sortAsc = !model.sortAsc;
1064
            } else {
1065
                model.sortCol = modelIndex;
1066
            }
1067
            model.sortData();
1068
            sqlHistoryTable.tableChanged(new TableModelEvent(model));
1069
            sqlHistoryTable.repaint();
1070
        }
1071
    }
1072
1073
    private class SQLComparator implements Comparator<SQLHistory> {
1074
1075
        protected int sortCol;
1076
        protected boolean sortAsc;
1077
1078
        public SQLComparator(int sortCol, boolean sortAsc) {
1079
            this.sortCol = sortCol;
1080
            this.sortAsc = sortAsc;
1081
        }
1082
1083
        @Override
1084
        public int compare(SQLHistory sql1, SQLHistory sql2) {
1085
            int result = 0;
1086
            if (!(sql1 instanceof SQLHistory) || !(sql2 instanceof SQLHistory)) {
1087
                return result;
1088
            }
1089
            SQLHistory sqlHistory1 = sql1;
1090
            SQLHistory sqlHistory2 = sql2;
1091
1092
            switch (sortCol) {
1093
                case 0: // SQL
1094
                    String s1 = sqlHistory1.getSql().trim().toLowerCase();
1095
                    String s2 = sqlHistory2.getSql().trim().toLowerCase();
1096
                    result = s1.compareTo(s2);
1097
                    break;
1098
                case 1: // Date
1099
                    Date d1 = sqlHistory1.getDate();
1100
                    Date d2 = sqlHistory2.getDate();
1101
                    result = d1.compareTo(d2);
1102
                    break;
1103
            }
1104
            if (!sortAsc) {
1105
                result = -result;
1106
            }
1107
            return result;
1108
        }
1109
1110
        @Override
1111
        public boolean equals(Object obj) {
1112
            if (obj instanceof SQLComparator) {
1113
                SQLComparator compObj = (SQLComparator) obj;
1114
                return (compObj.sortCol == sortCol) && (compObj.sortAsc == sortAsc);
1115
            }
1116
            return false;
1117
        }
1118
1119
        @Override
1120
        public int hashCode() {
1121
            int hash = 3;
1122
            hash = 17 * hash + this.sortCol;
1123
            hash = 17 * hash + (this.sortAsc ? 1 : 0);
1124
            return hash;
1125
        }
1126
    }
1127
}
605
}
(-)a/db.core/src/org/netbeans/modules/db/sql/history/SQLHistory.java (-60 / +110 lines)
Lines 1-74 Link Here
1
/*
2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3
 *
4
 * Copyright 2008-2010 Oracle and/or its affiliates. All rights reserved.
5
 *
6
 * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
7
 * Other names may be trademarks of their respective owners.
8
 *
9
 * The contents of this file are subject to the terms of either the GNU
10
 * General Public License Version 2 only ("GPL") or the Common
11
 * Development and Distribution License("CDDL") (collectively, the
12
 * "License"). You may not use this file except in compliance with the
13
 * License. You can obtain a copy of the License at
14
 * http://www.netbeans.org/cddl-gplv2.html
15
 * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
16
 * specific language governing permissions and limitations under the
17
 * License.  When distributing the software, include this License Header
18
 * Notice in each file and include the License file at
19
 * nbbuild/licenses/CDDL-GPL-2-CP.  Oracle designates this
20
 * particular file as subject to the "Classpath" exception as provided
21
 * by Oracle in the GPL Version 2 section of the License file that
22
 * accompanied this code. If applicable, add the following below the
23
 * License Header, with the fields enclosed by brackets [] replaced by
24
 * your own identifying information:
25
 * "Portions Copyrighted [year] [name of copyright owner]"
26
 * 
27
 * If you wish your version of this file to be governed by only the CDDL
28
 * or only the GPL Version 2, indicate your decision by adding
29
 * "[Contributor] elects to include this software in this distribution
30
 * under the [CDDL or GPL Version 2] license." If you do not indicate a
31
 * single choice of license, a recipient has the option to distribute
32
 * your version of this file under either the CDDL, the GPL Version 2 or
33
 * to extend the choice of license to its licensees as provided above.
34
 * However, if you add GPL Version 2 code and therefore, elected the GPL
35
 * Version 2 license, then the option applies only if the new code is
36
 * made subject to such option by the copyright holder.
37
 * 
38
 * Contributor(s):
39
 * 
40
 * Portions Copyrighted 2008-2010 Sun Microsystems, Inc.
41
 */
42
1
43
package org.netbeans.modules.db.sql.history;
2
package org.netbeans.modules.db.sql.history;
44
3
45
import java.util.Date;
4
import java.util.ArrayList;
5
import java.util.Collection;
6
import java.util.Collections;
7
import java.util.Comparator;
8
import java.util.HashSet;
9
import java.util.Iterator;
10
import java.util.List;
11
import java.util.Set;
12
import javax.xml.bind.annotation.XmlElement;
13
import javax.xml.bind.annotation.XmlRootElement;
14
import javax.xml.bind.annotation.XmlTransient;
46
15
47
/**
16
@XmlRootElement(name="history")
48
 *
17
public class SQLHistory implements Set<SQLHistoryEntry> {
49
 * @author John Baker
18
    @XmlTransient
50
 */
19
    private int historyLimit = 100;
51
public class SQLHistory {
20
    @XmlElement(name="sql")
52
    String sql;
21
    private Set<SQLHistoryEntry> history;
53
    String url;
22
54
    Date   date;
23
    public SQLHistory() {
24
        history = new HashSet<SQLHistoryEntry>();
25
    }
26
27
    public String toString() {
28
        return history.toString();
29
    }
30
31
    public <T> T[] toArray(T[] a) {
32
        return history.toArray(a);
33
    }
34
35
    public Object[] toArray() {
36
        return history.toArray();
37
    }
38
39
    public int size() {
40
        return history.size();
41
    }
42
43
    public boolean retainAll(Collection<?> c) {
44
        return history.retainAll(c);
45
    }
46
47
    public boolean removeAll(Collection<?> c) {
48
        return history.removeAll(c);
49
    }
50
51
    public boolean remove(Object o) {
52
        return history.remove(o);
53
    }
54
55
    public Iterator<SQLHistoryEntry> iterator() {
56
        return history.iterator();
57
    }
55
     
58
     
56
    public SQLHistory(String url, String sql, Date date) {
59
    public boolean isEmpty() {
57
        this.url = url;
60
        return history.isEmpty();
58
        this.sql = sql;
59
        this.date = date;
60
    }
61
    }
61
    
62
    
62
    public String getUrl() {
63
    public int hashCode() {
63
        return url;
64
        return history.hashCode();
64
    }
65
    }
65
    
66
    
66
    public String getSql() {
67
    public boolean equals(Object o) {
67
        return sql;
68
        return history.equals(o);
68
    }
69
    }
69
    
70
    
70
    public Date getDate() {
71
    public boolean containsAll(Collection<?> c) {
71
        return date;
72
        return history.containsAll(c);
72
    }
73
    }
73
74
75
    public boolean contains(Object o) {
76
        return history.contains(o);
77
    }
78
79
    public void clear() {
80
        history.clear();
81
    }
82
     
83
    public boolean addAll(Collection<? extends SQLHistoryEntry> c) {
84
        boolean changed = false;
85
        for(SQLHistoryEntry sqe: c) {
86
            changed |= this.add(sqe);
87
        }
88
        return changed;
89
    }
90
    
91
    public boolean add(SQLHistoryEntry e) {
92
        boolean result = history.add(e);
93
        if(! result) {
94
            history.remove(e);
95
            result = history.add(e);
96
        }
97
        enforceLimit();
98
        return result;
99
    }
100
    
101
    public void enforceLimit() {
102
        if(size() > historyLimit) {
103
            List<SQLHistoryEntry> list = new ArrayList<SQLHistoryEntry>(history);
104
            Collections.sort(list, new Comparator<SQLHistoryEntry>() {
105
                @Override
106
                public int compare(SQLHistoryEntry o1, SQLHistoryEntry o2) {
107
                    return o2.getDate().compareTo(o1.getDate());
108
                }
109
            });
110
            history.clear();
111
            history.addAll(list.subList(0, historyLimit));
112
        }
113
    }
114
    
115
    @XmlTransient
116
    public int getHistoryLimit() {
117
        return historyLimit;
118
    }
119
120
    public void setHistoryLimit(int historyLimit) {
121
        this.historyLimit = historyLimit;
122
        enforceLimit();
123
    }
74
}
124
}
(-)a/db.core/src/org/netbeans/modules/db/sql/history/SQLHistoryEntry.java (+152 lines)
Line 0 Link Here
1
/*
2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3
 *
4
 * Copyright 2011 Oracle and/or its affiliates. All rights reserved.
5
 *
6
 * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
7
 * Other names may be trademarks of their respective owners.
8
 *
9
 * The contents of this file are subject to the terms of either the GNU
10
 * General Public License Version 2 only ("GPL") or the Common
11
 * Development and Distribution License("CDDL") (collectively, the
12
 * "License"). You may not use this file except in compliance with the
13
 * License. You can obtain a copy of the License at
14
 * http://www.netbeans.org/cddl-gplv2.html
15
 * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
16
 * specific language governing permissions and limitations under the
17
 * License.  When distributing the software, include this License Header
18
 * Notice in each file and include the License file at
19
 * nbbuild/licenses/CDDL-GPL-2-CP.  Oracle designates this
20
 * particular file as subject to the "Classpath" exception as provided
21
 * by Oracle in the GPL Version 2 section of the License file that
22
 * accompanied this code. If applicable, add the following below the
23
 * License Header, with the fields enclosed by brackets [] replaced by
24
 * your own identifying information:
25
 * "Portions Copyrighted [year] [name of copyright owner]"
26
 *
27
 * If you wish your version of this file to be governed by only the CDDL
28
 * or only the GPL Version 2, indicate your decision by adding
29
 * "[Contributor] elects to include this software in this distribution
30
 * under the [CDDL or GPL Version 2] license." If you do not indicate a
31
 * single choice of license, a recipient has the option to distribute
32
 * your version of this file under either the CDDL, the GPL Version 2 or
33
 * to extend the choice of license to its licensees as provided above.
34
 * However, if you add GPL Version 2 code and therefore, elected the GPL
35
 * Version 2 license, then the option applies only if the new code is
36
 * made subject to such option by the copyright holder.
37
 *
38
 * Contributor(s):
39
 *
40
 * Portions Copyrighted 2011 Sun Microsystems, Inc.
41
 */
42
package org.netbeans.modules.db.sql.history;
43
44
import java.text.DateFormat;
45
import java.text.ParseException;
46
import java.util.Date;
47
import javax.xml.bind.annotation.XmlAttribute;
48
import javax.xml.bind.annotation.XmlTransient;
49
import javax.xml.bind.annotation.XmlType;
50
import javax.xml.bind.annotation.XmlValue;
51
52
@XmlType(name = "sql")
53
public class SQLHistoryEntry {
54
55
    private String url;
56
    private String sql;
57
    private Date date;
58
59
    protected SQLHistoryEntry() {
60
    }
61
62
    public SQLHistoryEntry(String url, String sql, Date date) {
63
        this.url = url;
64
        this.sql = sql;
65
        this.date = date;
66
    }
67
68
    @XmlTransient
69
    public Date getDate() {
70
        return date;
71
    }
72
73
    protected void setDate(Date date) {
74
        this.date = date;
75
    }
76
77
    @XmlValue
78
    public String getSql() {
79
        return sql;
80
    }
81
82
    protected void setSql(String sql) {
83
        if (sql != null) {
84
            this.sql = sql.trim();
85
        } else {
86
            this.sql = sql;
87
        }
88
    }
89
90
    @XmlAttribute
91
    public String getUrl() {
92
        return url;
93
    }
94
95
    protected void setUrl(String url) {
96
        this.url = url;
97
    }
98
99
    @XmlAttribute(name = "date")
100
    protected String getDateXMLVariant() {
101
        if (this.date == null) {
102
            return null;
103
        } else {
104
            return Long.toString(date.getTime());
105
        }
106
    }
107
108
    protected void setDateXMLVariant(String value) {
109
        try {
110
            date = new Date(Long.parseLong(value));
111
        } catch (NumberFormatException nfe) {
112
            // #152486 - previously date stored in text format
113
            try {
114
                date = DateFormat.getDateTimeInstance(DateFormat.SHORT, DateFormat.SHORT).parse(value);
115
            } catch (ParseException pe) {
116
                // # 152486; Date stored is not parsable, so reset the date to the current timestamp
117
                date = new Date();
118
            }
119
        }
120
121
    }
122
123
    @Override
124
    public String toString() {
125
        return "SQLHistoryEntry{" + "url=" + url + ", sql=" + sql + ", date=" + date + '}';
126
    }
127
128
    @Override
129
    public boolean equals(Object obj) {
130
        if (obj == null) {
131
            return false;
132
        }
133
        if (getClass() != obj.getClass()) {
134
            return false;
135
        }
136
        final SQLHistoryEntry other = (SQLHistoryEntry) obj;
137
        if ((this.url == null) ? (other.url != null) : !this.url.toLowerCase().equals(other.url.toLowerCase())) {
138
            return false;
139
        }
140
        if ((this.sql == null) ? (other.sql != null) : !this.sql.toLowerCase().equals(other.sql.toLowerCase())) {
141
            return false;
142
        }
143
        return true;
144
    }
145
146
    @Override
147
    public int hashCode() {
148
        int hash = 7;
149
        hash = 37 * hash + (this.sql != null ? this.sql.toLowerCase().hashCode() : 0);
150
        return hash;
151
    }
152
}
(-)a/db.core/src/org/netbeans/modules/db/sql/history/SQLHistoryException.java (-58 lines)
Lines 1-58 Link Here
1
/*
2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3
 *
4
 * Copyright 2010 Oracle and/or its affiliates. All rights reserved.
5
 *
6
 * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
7
 * Other names may be trademarks of their respective owners.
8
 *
9
 * The contents of this file are subject to the terms of either the GNU
10
 * General Public License Version 2 only ("GPL") or the Common
11
 * Development and Distribution License("CDDL") (collectively, the
12
 * "License"). You may not use this file except in compliance with the
13
 * License. You can obtain a copy of the License at
14
 * http://www.netbeans.org/cddl-gplv2.html
15
 * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
16
 * specific language governing permissions and limitations under the
17
 * License.  When distributing the software, include this License Header
18
 * Notice in each file and include the License file at
19
 * nbbuild/licenses/CDDL-GPL-2-CP.  Oracle designates this
20
 * particular file as subject to the "Classpath" exception as provided
21
 * by Oracle in the GPL Version 2 section of the License file that
22
 * accompanied this code. If applicable, add the following below the
23
 * License Header, with the fields enclosed by brackets [] replaced by
24
 * your own identifying information:
25
 * "Portions Copyrighted [year] [name of copyright owner]"
26
 *
27
 * If you wish your version of this file to be governed by only the CDDL
28
 * or only the GPL Version 2, indicate your decision by adding
29
 * "[Contributor] elects to include this software in this distribution
30
 * under the [CDDL or GPL Version 2] license." If you do not indicate a
31
 * single choice of license, a recipient has the option to distribute
32
 * your version of this file under either the CDDL, the GPL Version 2 or
33
 * to extend the choice of license to its licensees as provided above.
34
 * However, if you add GPL Version 2 code and therefore, elected the GPL
35
 * Version 2 license, then the option applies only if the new code is
36
 * made subject to such option by the copyright holder.
37
 *
38
 * Contributor(s):
39
 *
40
 * Portions Copyrighted 2008 Sun Microsystems, Inc.
41
 */
42
43
package org.netbeans.modules.db.sql.history;
44
45
/**
46
 *
47
 * @author jbaker
48
 */
49
public class SQLHistoryException extends Exception {
50
    SQLHistoryException() {
51
    }
52
53
    SQLHistoryException(String msg) {
54
    }
55
56
    SQLHistoryException(String msg, Throwable cause) {
57
    }
58
}
(-)a/db.core/src/org/netbeans/modules/db/sql/history/SQLHistoryManager.java (-99 / +85 lines)
Lines 41-71 Link Here
41
 */
41
 */
42
package org.netbeans.modules.db.sql.history;
42
package org.netbeans.modules.db.sql.history;
43
43
44
44
import java.io.IOException;
45
import java.util.ArrayList;
45
import java.io.InputStream;
46
import java.util.List;
46
import java.io.OutputStream;
47
import java.util.logging.Level;
47
import java.util.logging.Level;
48
import java.util.logging.Logger;
48
import java.util.logging.Logger;
49
import javax.xml.bind.JAXBContext;
50
import javax.xml.bind.JAXBException;
51
import javax.xml.bind.Marshaller;
52
import javax.xml.bind.Unmarshaller;
49
import org.netbeans.modules.db.sql.execute.ui.SQLHistoryPanel;
53
import org.netbeans.modules.db.sql.execute.ui.SQLHistoryPanel;
50
import org.openide.filesystems.FileObject;
54
import org.openide.filesystems.FileObject;
51
import org.openide.filesystems.FileUtil;
55
import org.openide.filesystems.FileUtil;
52
import org.openide.util.NbBundle;
56
import org.openide.util.Exceptions;
57
import org.openide.util.NbPreferences;
53
58
54
/**
59
/**
55
 *
60
 *
56
 * @author John Baker
61
 * @author John Baker
57
 */
62
 */
58
public class SQLHistoryManager  {
63
public class SQLHistoryManager  {
59
    public static final String SQL_HISTORY_FOLDER = "Databases/SQLHISTORY"; // NOI18N
64
60
    public static final String SQL_HISTORY_FILE_NAME = "sql_history.xml";  // NOI18N
65
    JAXBContext context;
61
    public static final String SAVE_STATEMENTS_MAX_LIMIT_ENTERED = "100"; // NOI18N
66
    private static final String SQL_HISTORY_DIRECTORY = "Databases/SQLHISTORY"; // NOI18N
67
    private static final String SQL_HISTORY_FILE = "sql_history.xml"; // NOI18N
68
    public static final String OPT_SQL_STATEMENTS_SAVED_FOR_HISTORY = "SQL_STATEMENTS_SAVED_FOR_HISTORY"; // NOI18N
69
    public static final int DEFAULT_SQL_STATEMENTS_SAVED_FOR_HISTORY = 100;
70
    public static final int MAX_SQL_STATEMENTS_SAVED_FOR_HISTORY = 10000;
62
    private static SQLHistoryManager _instance = null;    
71
    private static SQLHistoryManager _instance = null;    
63
    private static final Logger LOGGER = Logger.getLogger(SQLHistory.class.getName());
72
    private static final Logger LOGGER = Logger.getLogger(SQLHistoryEntry.class.getName());
64
    private List<SQLHistory> sqlList = new ArrayList<SQLHistory>();
73
    private SQLHistory sqlHistory;
65
    private int listSize;
66
    private FileObject historyRoot;
67
74
68
    private SQLHistoryManager() {
75
    protected SQLHistoryManager() {
76
        ClassLoader orig = Thread.currentThread().getContextClassLoader();
77
        Thread.currentThread().setContextClassLoader(SQLHistoryManager.class.getClassLoader());
78
        try {
79
            context = JAXBContext.newInstance("org.netbeans.modules.db.sql.history", SQLHistoryManager.class.getClassLoader());
80
            loadHistory();
81
        } catch (JAXBException ex) {
82
            throw new RuntimeException(ex);
83
        } finally {
84
            Thread.currentThread().setContextClassLoader(orig);
85
        }
69
    }
86
    }
70
    
87
    
71
    public static SQLHistoryManager getInstance() {
88
    public static SQLHistoryManager getInstance() {
Lines 75-181 Link Here
75
        return _instance;
92
        return _instance;
76
    }
93
    }
77
94
78
    /**
79
     * Get the value of listSize
80
     *
81
     * @return the value of listSize
82
     */
83
    public int getListSize() {
95
    public int getListSize() {
84
        return listSize;
96
        return NbPreferences.forModule(SQLHistoryPanel.class).getInt("OPT_SQL_STATEMENTS_SAVED_FOR_HISTORY", DEFAULT_SQL_STATEMENTS_SAVED_FOR_HISTORY);
97
    }
98
99
    protected FileObject getHistoryRoot(boolean create) throws IOException {
100
        FileObject result = null;
101
        FileObject historyRootDir = getConfigRoot().getFileObject(getRelativeHistoryPath());
102
        if (historyRootDir != null || create) {
103
            if (historyRootDir == null) {
104
                historyRootDir = FileUtil.createFolder(getConfigRoot(), getRelativeHistoryPath());
105
    }
106
            FileObject historyRoot = historyRootDir.getFileObject(getHistoryFilename());
107
108
            if (historyRoot != null || create) {
109
                if(historyRoot == null) {
110
                    historyRoot = historyRootDir.createData(getHistoryFilename());
111
    }
112
                result = historyRoot;
113
    }
114
        }
115
        return result;
85
    }
116
    }
86
    
117
    
87
    public FileObject getHistoryRoot() {
118
    protected FileObject getConfigRoot() {
88
        return historyRoot;
119
        return FileUtil.getConfigRoot();
120
    }
121
    
122
    protected String getRelativeHistoryPath() {
123
        return SQL_HISTORY_DIRECTORY;
89
    }
124
    }
90
125
91
    public void setHistoryRoot(FileObject root) {
126
    protected String getHistoryFilename() {
92
        historyRoot = root;
127
        return SQL_HISTORY_FILE;
128
                }
129
130
    public void setListSize(int listSize) {
131
        NbPreferences.forModule(SQLHistoryPanel.class).putInt("OPT_SQL_STATEMENTS_SAVED_FOR_HISTORY", listSize);
132
        sqlHistory.setHistoryLimit(listSize);
93
    }
133
    }
94
134
95
    /**
135
    public void saveSQL(SQLHistoryEntry sqlStored) {
96
     * Set the value of listSize
136
        sqlHistory.add(sqlStored);
97
     *
137
            }
98
     * @param listSize new value of listSize
99
     */
100
    public void setListSize(int listSize) {
101
        this.listSize = listSize;
102
    }
103
138
104
    
139
    private void loadHistory() {
105
    public void saveSQL(SQLHistory sqlStored) {
106
        sqlList.add(sqlStored);
107
    }
108
    
109
    public void save(FileObject userdirRoot) {
110
        try {
140
        try {
111
            // create a folder in the userdir for sql_history.xml file that maintains a list of executed SQL
141
            Unmarshaller unmarshaller = context.createUnmarshaller();
112
            setHistoryRoot(userdirRoot.getFileObject(SQL_HISTORY_FOLDER));
142
            InputStream is = getHistoryRoot(false).getInputStream();
113
            if (null == historyRoot || !historyRoot.isValid()) {
143
            sqlHistory = (SQLHistory) unmarshaller.unmarshal(is);
114
                historyRoot = FileUtil.createFolder(userdirRoot, SQL_HISTORY_FOLDER);
144
            sqlHistory.setHistoryLimit(getListSize());
115
            }
145
            is.close();
116
            // Start managing the persistence of SQL statements that have been executed
117
            SQLHistoryPersistenceManager.getInstance().create(historyRoot, sqlList);
118
            sqlList.clear();
119
        } catch (Exception ex) {
146
        } catch (Exception ex) {
147
            sqlHistory = new SQLHistory();
148
            sqlHistory.setHistoryLimit(getListSize());
120
            LOGGER.log(Level.INFO, ex.getMessage());
149
            LOGGER.log(Level.INFO, ex.getMessage());
121
            LOGGER.log(Level.INFO, NbBundle.getMessage(SQLHistoryManager.class, "MSG_ErrorParsingHistoryFile"));
122
        }
150
        }
123
    }
151
    }
124
    
152
    
125
    public List<SQLHistory> getSQLHistory() {
153
    public void save() {
126
        return sqlList;
154
        try {
127
    }
155
            Marshaller marshaller = context.createMarshaller();
128
    
156
            OutputStream os = getHistoryRoot(true).getOutputStream();
129
    public List<SQLHistory> retrieve() {
157
            marshaller.marshal(sqlHistory, os);
130
        return new ArrayList<SQLHistory>();
158
            os.close();
131
        
159
        } catch (Exception ex) {
132
    }
160
            LOGGER.log(Level.INFO, ex.getMessage());
161
            }
162
        }    
133
163
134
    public List<String> retrieve(String url) {
164
    public SQLHistory getSQLHistory() {
135
        List<String> sqlAsString = new ArrayList<String>();
165
        return sqlHistory;
136
        String sql;
137
        if (!getUrlsUsed().isEmpty()) {
138
            for (SQLHistory historyItem : sqlList) {
139
                sql = historyItem.getSql();
140
                if (url.equals(historyItem.getUrl())) {
141
                    sqlAsString.add(sql);
142
                }
143
            }
144
        }
145
        return sqlAsString;
146
147
    }
148
149
    private List<String> getUrlsUsed() {
150
        List<String> urls = new ArrayList<String>();
151
        String url;
152
        for (SQLHistory historyItem : sqlList) {
153
            url = historyItem.getUrl();
154
            if (!urls.contains(url)) {
155
                urls.add(url);
156
            }
157
        }
158
        return urls;
159
    }
160
    
161
    public int updateList(int limit, String historyFilePath, FileObject root) throws SQLHistoryException {
162
        List<SQLHistory> updatedSQLHistoryList = new ArrayList<SQLHistory>();
163
        int numItemsToRemove = 0;
164
        try {
165
            updatedSQLHistoryList = SQLHistoryPersistenceManager.getInstance().retrieve(root);
166
            if (limit >= updatedSQLHistoryList.size()) {
167
                // no changes needed to the current list
168
                return -1;
169
            }
170
            // Remove elements from list based on the number of statements to save that is set in the SQL History dialog
171
            numItemsToRemove = updatedSQLHistoryList.size() - limit;
172
            for (int i = 0; i < numItemsToRemove; i++) {
173
                updatedSQLHistoryList.remove(0);
174
            }
175
         } catch (ClassNotFoundException ex) {
176
            LOGGER.log(Level.INFO, NbBundle.getMessage(SQLHistoryPanel.class, "MSG_RuntimeErrorRetrievingHistory") + ex);
177
        }    
178
        sqlList = updatedSQLHistoryList;
179
        return numItemsToRemove;
180
    }
166
    }
181
}
167
}
(-)a/db.core/src/org/netbeans/modules/db/sql/history/SQLHistoryModel.java (-62 lines)
Lines 1-62 Link Here
1
/*
2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3
 *
4
 * Copyright 2010 Oracle and/or its affiliates. All rights reserved.
5
 *
6
 * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
7
 * Other names may be trademarks of their respective owners.
8
 *
9
 * The contents of this file are subject to the terms of either the GNU
10
 * General Public License Version 2 only ("GPL") or the Common
11
 * Development and Distribution License("CDDL") (collectively, the
12
 * "License"). You may not use this file except in compliance with the
13
 * License. You can obtain a copy of the License at
14
 * http://www.netbeans.org/cddl-gplv2.html
15
 * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
16
 * specific language governing permissions and limitations under the
17
 * License.  When distributing the software, include this License Header
18
 * Notice in each file and include the License file at
19
 * nbbuild/licenses/CDDL-GPL-2-CP.  Oracle designates this
20
 * particular file as subject to the "Classpath" exception as provided
21
 * by Oracle in the GPL Version 2 section of the License file that
22
 * accompanied this code. If applicable, add the following below the
23
 * License Header, with the fields enclosed by brackets [] replaced by
24
 * your own identifying information:
25
 * "Portions Copyrighted [year] [name of copyright owner]"
26
 * 
27
 * If you wish your version of this file to be governed by only the CDDL
28
 * or only the GPL Version 2, indicate your decision by adding
29
 * "[Contributor] elects to include this software in this distribution
30
 * under the [CDDL or GPL Version 2] license." If you do not indicate a
31
 * single choice of license, a recipient has the option to distribute
32
 * your version of this file under either the CDDL, the GPL Version 2 or
33
 * to extend the choice of license to its licensees as provided above.
34
 * However, if you add GPL Version 2 code and therefore, elected the GPL
35
 * Version 2 license, then the option applies only if the new code is
36
 * made subject to such option by the copyright holder.
37
 * 
38
 * Contributor(s):
39
 * 
40
 * Portions Copyrighted 2008 Sun Microsystems, Inc.
41
 */
42
43
package org.netbeans.modules.db.sql.history;
44
45
import java.util.List;
46
47
/**
48
 *
49
 * @author John Baker
50
 */
51
public interface SQLHistoryModel {
52
    void initialize();
53
    
54
    void setFilter(String filter);
55
        
56
    String getFilter();
57
    
58
    List<SQLHistory> getSQLHistoryList() throws SQLHistoryException;
59
    
60
    void setSQLHistoryList(List<SQLHistory> sqlHistoryList);
61
    
62
}
(-)a/db.core/src/org/netbeans/modules/db/sql/history/SQLHistoryModelImpl.java (-177 lines)
Lines 1-177 Link Here
1
/*
2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3
 *
4
 * Copyright 2010 Oracle and/or its affiliates. All rights reserved.
5
 *
6
 * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
7
 * Other names may be trademarks of their respective owners.
8
 *
9
 * The contents of this file are subject to the terms of either the GNU
10
 * General Public License Version 2 only ("GPL") or the Common
11
 * Development and Distribution License("CDDL") (collectively, the
12
 * "License"). You may not use this file except in compliance with the
13
 * License. You can obtain a copy of the License at
14
 * http://www.netbeans.org/cddl-gplv2.html
15
 * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
16
 * specific language governing permissions and limitations under the
17
 * License.  When distributing the software, include this License Header
18
 * Notice in each file and include the License file at
19
 * nbbuild/licenses/CDDL-GPL-2-CP.  Oracle designates this
20
 * particular file as subject to the "Classpath" exception as provided
21
 * by Oracle in the GPL Version 2 section of the License file that
22
 * accompanied this code. If applicable, add the following below the
23
 * License Header, with the fields enclosed by brackets [] replaced by
24
 * your own identifying information:
25
 * "Portions Copyrighted [year] [name of copyright owner]"
26
 * 
27
 * If you wish your version of this file to be governed by only the CDDL
28
 * or only the GPL Version 2, indicate your decision by adding
29
 * "[Contributor] elects to include this software in this distribution
30
 * under the [CDDL or GPL Version 2] license." If you do not indicate a
31
 * single choice of license, a recipient has the option to distribute
32
 * your version of this file under either the CDDL, the GPL Version 2 or
33
 * to extend the choice of license to its licensees as provided above.
34
 * However, if you add GPL Version 2 code and therefore, elected the GPL
35
 * Version 2 license, then the option applies only if the new code is
36
 * made subject to such option by the copyright holder.
37
 * 
38
 * Contributor(s):
39
 * 
40
 * Portions Copyrighted 2010 Sun Microsystems, Inc.
41
 */
42
43
package org.netbeans.modules.db.sql.history;
44
45
import java.util.ArrayList;
46
import java.util.Collections;
47
import java.util.List;
48
import java.util.logging.Logger;
49
import org.openide.filesystems.FileObject;
50
import org.openide.filesystems.FileUtil;
51
import org.openide.util.NbPreferences;
52
53
/**
54
 *
55
 * @author John Baker
56
 */
57
public class SQLHistoryModelImpl implements SQLHistoryModel {    
58
    private static final int SAVE_STATEMENTS_EMPTY = 0; // NOI18N
59
    private static final String SAVE_STATEMENTS_CLEARED = ""; // NOI18N  
60
    private static final Logger LOGGER = Logger.getLogger(SQLHistoryModelImpl.class.getName());
61
    private static final FileObject USERDIR = FileUtil.getConfigRoot();
62
63
    List<SQLHistory> _sqlHistoryList = new ArrayList<SQLHistory>();
64
    
65
    @Override
66
    public void initialize() {
67
        throw new UnsupportedOperationException("Not supported yet.");
68
    }
69
70
    @Override
71
    public void setFilter(String filter) {
72
        throw new UnsupportedOperationException("Not supported yet.");
73
    }
74
75
    @Override
76
    public String getFilter() {
77
        throw new UnsupportedOperationException("Not supported yet.");
78
    }
79
80
    @Override
81
    public List<SQLHistory> getSQLHistoryList() throws SQLHistoryException {
82
        List<SQLHistory> retrievedSQL = new ArrayList<SQLHistory>();
83
        _sqlHistoryList.clear();
84
        try {
85
            boolean isRewriteSQLRequired = false;
86
            FileObject historyRoot = USERDIR.getFileObject(SQLHistoryManager.SQL_HISTORY_FOLDER);
87
            if (historyRoot == null) {
88
                return new ArrayList<SQLHistory>();
89
            }
90
            // Read persisted SQL from  file            
91
            retrievedSQL = SQLHistoryPersistenceManager.getInstance().retrieve(historyRoot);
92
            // Remove duplicates
93
            if (!isSQLUnique(retrievedSQL)) {
94
                retrievedSQL = removeDuplicates(retrievedSQL);
95
                isRewriteSQLRequired = true;
96
            }
97
            // Get saved limit
98
            String savedLimit = NbPreferences.forModule(SQLHistoryPersistenceManager.class).get("SQL_STATEMENTS_SAVED_FOR_HISTORY", "");
99
            if (savedLimit.equals(SAVE_STATEMENTS_CLEARED)) {
100
                savedLimit = SQLHistoryManager.SAVE_STATEMENTS_MAX_LIMIT_ENTERED;
101
            }
102
            int limit = Integer.parseInt(savedLimit);
103
            // Remove any elements if save limit is exceeded
104
            if (retrievedSQL.size() > limit) {
105
                retrievedSQL = removeExtraSQL(retrievedSQL, limit);
106
                isRewriteSQLRequired = true;
107
            }
108
            if (isRewriteSQLRequired) {
109
                // Remove all elements from sql_history.xml
110
                SQLHistoryPersistenceManager.getInstance().updateSQLSaved(SAVE_STATEMENTS_EMPTY, historyRoot);
111
                // Write new list;  reversing list is required for persisting the SQL
112
                Collections.reverse(retrievedSQL);
113
                SQLHistoryPersistenceManager.getInstance().create(historyRoot, retrievedSQL);
114
                // return list to the expected order for viewing
115
                Collections.reverse(retrievedSQL);
116
            }
117
        } catch (ClassNotFoundException ex) {
118
            throw new SQLHistoryException();
119
        }
120
        return retrievedSQL;
121
    }
122
    
123
    private boolean isSQLUnique(List<SQLHistory> sqlHistoryList) {
124
        List<SQLHistory> revSqLHistoryList = new ArrayList<SQLHistory>();
125
        boolean isUnique = true;
126
127
        for (SQLHistory sqlHistory : sqlHistoryList) {
128
            for (SQLHistory revHistory : revSqLHistoryList) {
129
                if (revHistory.getSql().trim().equals(sqlHistory.getSql().trim())) {
130
                    if (revHistory.getUrl().equals(sqlHistory.getUrl())) {
131
                        isUnique = false;
132
                    }
133
                }
134
            }
135
            revSqLHistoryList.add(sqlHistory);
136
        }
137
        return isUnique;
138
    }
139
    
140
    private List<SQLHistory> removeDuplicates(List<SQLHistory> sqlHistoryList) {
141
         List<SQLHistory> revSqLHistoryList = new ArrayList<SQLHistory>();
142
         boolean canAdd = true;
143
            for (SQLHistory sqlHistory : sqlHistoryList) {
144
                for (SQLHistory revHistory : revSqLHistoryList) {
145
                    if (revHistory.getSql().trim().equals(sqlHistory.getSql().trim())) {
146
                        if (revHistory.getUrl().equals(sqlHistory.getUrl())) {
147
                            canAdd = false;
148
                        }
149
                    }
150
                }
151
                if (canAdd) {
152
                    revSqLHistoryList.add(sqlHistory);
153
                } else {
154
                    canAdd = true;
155
                }
156
            }
157
            return revSqLHistoryList;        
158
    }
159
    
160
    private List<SQLHistory> removeExtraSQL(List<SQLHistory> sqlHistoryList, int limit) {
161
        int i = 0;
162
        List<SQLHistory> revSqLHistoryList = new ArrayList<SQLHistory>();
163
164
        for (SQLHistory sqlHistory : sqlHistoryList) {
165
            if (i < limit) {
166
                revSqLHistoryList.add(sqlHistory);
167
            }
168
            i++;
169
        }    
170
        return revSqLHistoryList;
171
    }
172
173
    @Override
174
    public void setSQLHistoryList(List<SQLHistory> sqlHistoryList) {
175
        _sqlHistoryList = sqlHistoryList;
176
    }
177
}
(-)a/db.core/src/org/netbeans/modules/db/sql/history/SQLHistoryPersistenceManager.java (-572 lines)
Lines 1-572 Link Here
1
/*
2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3
 *
4
 * Copyright 1997-2010 Oracle and/or its affiliates. All rights reserved.
5
 *
6
 * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
7
 * Other names may be trademarks of their respective owners.
8
 *
9
 * The contents of this file are subject to the terms of either the GNU
10
 * General Public License Version 2 only ("GPL") or the Common
11
 * Development and Distribution License("CDDL") (collectively, the
12
 * "License"). You may not use this file except in compliance with the
13
 * License. You can obtain a copy of the License at
14
 * http://www.netbeans.org/cddl-gplv2.html
15
 * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
16
 * specific language governing permissions and limitations under the
17
 * License.  When distributing the software, include this License Header
18
 * Notice in each file and include the License file at
19
 * nbbuild/licenses/CDDL-GPL-2-CP.  Oracle designates this
20
 * particular file as subject to the "Classpath" exception as provided
21
 * by Oracle in the GPL Version 2 section of the License file that
22
 * accompanied this code. If applicable, add the following below the
23
 * License Header, with the fields enclosed by brackets [] replaced by
24
 * your own identifying information:
25
 * "Portions Copyrighted [year] [name of copyright owner]"
26
 *
27
 * Contributor(s):
28
 *
29
 * The Original Software is NetBeans. The Initial Developer of the Original
30
 * Software is Sun Microsystems, Inc. Portions Copyright 1997-2010 Sun
31
 * Microsystems, Inc. All Rights Reserved.
32
 *
33
 * If you wish your version of this file to be governed by only the CDDL
34
 * or only the GPL Version 2, indicate your decision by adding
35
 * "[Contributor] elects to include this software in this distribution
36
 * under the [CDDL or GPL Version 2] license." If you do not indicate a
37
 * single choice of license, a recipient has the option to distribute
38
 * your version of this file under either the CDDL, the GPL Version 2 or
39
 * to extend the choice of license to its licensees as provided above.
40
 * However, if you add GPL Version 2 code and therefore, elected the GPL
41
 * Version 2 license, then the option applies only if the new code is
42
 * made subject to such option by the copyright holder.
43
 */
44
package org.netbeans.modules.db.sql.history;
45
46
import java.io.File;
47
import java.io.IOException;
48
import java.io.InputStream;
49
import java.io.OutputStream;
50
import java.io.OutputStreamWriter;
51
import java.io.PrintWriter;
52
import java.text.DateFormat;
53
import java.text.ParseException;
54
import java.util.ArrayList;
55
import java.util.Calendar;
56
import java.util.Collections;
57
import java.util.Date;
58
import java.util.List;
59
import org.openide.util.Exceptions;
60
import org.xml.sax.Attributes;
61
import java.util.logging.Level;
62
import java.util.logging.Logger;
63
import javax.xml.parsers.DocumentBuilder;
64
import javax.xml.parsers.DocumentBuilderFactory;
65
import javax.xml.parsers.ParserConfigurationException;
66
import org.openide.filesystems.FileLock;
67
import org.openide.filesystems.FileObject;
68
import org.openide.filesystems.FileSystem;
69
import org.openide.filesystems.FileUtil;
70
import org.openide.loaders.DataFolder;
71
import org.openide.loaders.XMLDataObject;
72
import org.openide.util.NbPreferences;
73
import org.openide.xml.EntityCatalog;
74
import org.openide.xml.XMLUtil;
75
import org.w3c.dom.Document;
76
import org.w3c.dom.Element;
77
import org.w3c.dom.NamedNodeMap;
78
import org.w3c.dom.Node;
79
import org.w3c.dom.NodeList;
80
import org.w3c.dom.Text;
81
import org.xml.sax.ContentHandler;
82
import org.xml.sax.InputSource;
83
import org.xml.sax.SAXException;
84
import org.xml.sax.XMLReader;
85
import org.xml.sax.helpers.DefaultHandler;
86
87
/**
88
 * Manage creation and updates to persisted SQL statements
89
 *
90
 * @author John Baker
91
 */
92
public class SQLHistoryPersistenceManager {
93
    private static final int READ = 0;
94
    private static final int ADD = 1;
95
    private static final int REMOVE = 2;
96
    private static final int CREATE = 3;
97
    public static final Logger LOGGER = Logger.getLogger(SQLHistoryPersistenceManager.class.getName());
98
    private static SQLHistoryPersistenceManager _instance = null;
99
    private static Document document;
100
    private List<SQLHistory> sqlHistoryList;
101
    private int numElemsToRemove = 0;
102
103
    private SQLHistoryPersistenceManager() {
104
    }
105
106
    public static SQLHistoryPersistenceManager getInstance() {
107
        if (null == _instance) {
108
            _instance = new SQLHistoryPersistenceManager();
109
        }
110
        return _instance;
111
    }
112
113
    public void removeHistoryFile(FileObject historyRoot) {
114
        try {
115
            FileObject folder = DataFolder.findFolder(historyRoot).getPrimaryFile();
116
            String fn = FileUtil.getFileDisplayName(folder) + File.separator + SQLHistoryManager.SQL_HISTORY_FILE_NAME;
117
            FileObject historyFo = FileUtil.toFileObject(FileUtil.normalizeFile(new File(fn)));
118
            historyFo.delete();
119
        } catch (IOException ex) {
120
            Exceptions.printStackTrace(ex);
121
        }
122
123
    }
124
125
    public void create(FileObject historyFileObject, List<SQLHistory> sqlHistoryList) throws SQLHistoryException {
126
        try {
127
            this.sqlHistoryList = sqlHistoryList;
128
            DataFolder df = DataFolder.findFolder(historyFileObject);
129
            int action = df.getChildren().length == 0 ? CREATE : ADD;
130
            AtomicFileAction writer = new AtomicFileAction(df, null, action, sqlHistoryList);
131
            df.getPrimaryFile().getFileSystem().runAtomicAction(writer);
132
        } catch (IOException ex) {
133
            throw new SQLHistoryException(ex.getLocalizedMessage(), ex);
134
        }
135
    }
136
137
    public List<SQLHistory> retrieve(FileObject historyFileObject) throws ClassNotFoundException, SQLHistoryException {
138
        Handler handler = null;
139
        int limit;
140
        String limitUser = NbPreferences.forModule(SQLHistoryPersistenceManager.class).get("SQL_STATEMENTS_SAVED_FOR_HISTORY", "");
141
        if (!limitUser.isEmpty()) { // NOI18N
142
            try {
143
                limit = Integer.parseInt(limitUser);
144
            } catch (NumberFormatException nfe) {
145
                limit = Integer.parseInt(SQLHistoryManager.SAVE_STATEMENTS_MAX_LIMIT_ENTERED);
146
            }
147
        } else {
148
            limit = Integer.parseInt(SQLHistoryManager.SAVE_STATEMENTS_MAX_LIMIT_ENTERED);
149
        }
150
        try {
151
            handler = new Handler(limit);
152
            DataFolder df = DataFolder.findFolder(historyFileObject);
153
            AtomicFileAction reader = new AtomicFileAction(df, handler, READ, null);
154
            df.getPrimaryFile().getFileSystem().runAtomicAction(reader);
155
156
        } catch (IOException ex) {
157
            LOGGER.log(Level.FINE, ex.getLocalizedMessage(), ex);
158
            sqlHistoryList = handler.getXmlSqlHistoryList();
159
            throw new SQLHistoryException();
160
        }
161
        if (handler != null) {
162
            return handler.getXmlSqlHistoryList();
163
        } else {
164
            return new ArrayList<SQLHistory>();
165
        }
166
    }
167
168
    public List<SQLHistory> retrieve() {
169
        return sqlHistoryList;
170
    }
171
172
    public void setNumElemsToRemove(int elemsToRemove) {
173
        numElemsToRemove = elemsToRemove;
174
    }
175
176
    public int getNumElemsToRemove() {
177
        return numElemsToRemove;
178
    }
179
180
    public List<SQLHistory> updateSQLSaved(int limit, FileObject historyFileObject) throws SQLHistoryException {
181
        List<SQLHistory> updatedSQLHistoryList = null;
182
        try {
183
            if (historyFileObject == null) {
184
                return new ArrayList<SQLHistory>();
185
            }
186
            updatedSQLHistoryList = retrieve(historyFileObject);
187
            // Remove elements from list based on the number of statements to save that is set in the SQL History dialog
188
            if (limit < updatedSQLHistoryList.size()) {
189
                numElemsToRemove = updatedSQLHistoryList.size() - limit;
190
                boolean containsElems = true;
191
                containsElems = !updatedSQLHistoryList.isEmpty();
192
                if (containsElems && numElemsToRemove == updatedSQLHistoryList.size()) {
193
                    // remove all
194
                    DataFolder df = DataFolder.findFolder(historyFileObject);
195
                    List<SQLHistory> emptyList = Collections.emptyList();
196
                    AtomicFileAction writer = new AtomicFileAction(df, null, CREATE, emptyList);
197
                    df.getPrimaryFile().getFileSystem().runAtomicAction(writer);
198
                } else if (containsElems && (limit == 0 || numElemsToRemove >= 0)) {
199
                    DataFolder df = DataFolder.findFolder(historyFileObject);
200
                    AtomicFileAction modifier = new AtomicFileAction(df, null, REMOVE, updatedSQLHistoryList);
201
                    df.getPrimaryFile().getFileSystem().runAtomicAction(modifier);
202
                }
203
            }
204
            updatedSQLHistoryList = retrieve(historyFileObject);
205
        } catch (ClassNotFoundException ex) {
206
            throw new SQLHistoryException(ex.getLocalizedMessage(), ex);
207
        } catch (IOException ex) {
208
            throw new SQLHistoryException(ex.getLocalizedMessage(), ex);
209
        }
210
        return updatedSQLHistoryList;
211
    }
212
213
    private static final class AtomicFileAction implements FileSystem.AtomicAction {
214
        List<SQLHistory> sqlHistoryList;
215
        DataFolder parent;
216
        boolean remove;
217
        FileObject data;
218
        Handler handler;
219
        int actionType;
220
221
        AtomicFileAction(DataFolder parent, Handler handler, int actionType, List<SQLHistory> sqlHistoryList) {
222
            this.parent = parent;
223
            this.handler = handler;
224
            this.sqlHistoryList = sqlHistoryList;
225
            this.actionType = actionType;
226
        }
227
228
        @Override
229
        public void run() throws IOException {
230
            FileLock lck = null;
231
            OutputStream ostm = null;
232
            PrintWriter writer = null;
233
            XmlWriter xmlWriter = null;
234
            DocumentBuilderFactory factory = null;
235
            DocumentBuilder builder = null;
236
            try {
237
                FileObject folder = parent.getPrimaryFile();
238
                String fn = FileUtil.getFileDisplayName(folder) + File.separator + SQLHistoryManager.SQL_HISTORY_FILE_NAME;
239
                // Read, Write or Update the persisted SQL file
240
                switch (actionType) {
241
                    case READ:
242
                        FileObject historyFo = FileUtil.toFileObject(FileUtil.normalizeFile(new File(fn)));
243
                        XMLDataObject obj = (XMLDataObject) XMLDataObject.find(historyFo);
244
                        InputSource inputSource = new InputSource(obj.getPrimaryFile().getInputStream());
245
                        inputSource.setSystemId(historyFo.getURL().toExternalForm());
246
                        XMLReader reader = XMLUtil.createXMLReader();
247
                        reader.setContentHandler(handler);
248
                        reader.setErrorHandler(handler);
249
                        reader.setEntityResolver(EntityCatalog.getDefault());
250
                        reader.parse(inputSource);
251
                        break;
252
                    case ADD:
253
                        factory = DocumentBuilderFactory.newInstance();
254
                        builder = factory.newDocumentBuilder();
255
                        data = FileUtil.toFileObject(FileUtil.normalizeFile(new File(fn)));
256
                        InputStream inputStream = data.getInputStream();
257
                        document = builder.parse(inputStream);
258
                        inputStream.close();
259
                        lck = data.lock();
260
                        ostm = data.getOutputStream(lck);
261
                        writer = new PrintWriter(new OutputStreamWriter(ostm, "UTF8")); //NOI18N
262
                        // Create or update then write the DOM
263
                        xmlWriter = new XmlWriter(data, sqlHistoryList, writer);
264
                        xmlWriter.write(xmlWriter.createElements(document), ""); // NOI18N
265
                        break;
266
                    case CREATE:
267
                        factory = DocumentBuilderFactory.newInstance();
268
                        builder = factory.newDocumentBuilder();
269
                        if (new File(fn).exists()) {
270
                            data = folder.getFileObject(SQLHistoryManager.SQL_HISTORY_FILE_NAME);
271
                        } else {
272
                            data = folder.createData(SQLHistoryManager.SQL_HISTORY_FILE_NAME);
273
                        }
274
                        lck = data.lock();
275
                        ostm = data.getOutputStream(lck);
276
                        writer = new PrintWriter(new OutputStreamWriter(ostm, "UTF8")); //NOI18N
277
                        document = builder.newDocument();
278
                        xmlWriter = new XmlWriter(data, sqlHistoryList, writer);
279
                        xmlWriter.write();
280
                        // Create or update then write the DOM
281
                        xmlWriter = new XmlWriter(data, sqlHistoryList, writer);
282
                        xmlWriter.write(xmlWriter.createElements(document), ""); // NOI18N
283
                        break;
284
                    case REMOVE:
285
                        factory = DocumentBuilderFactory.newInstance();
286
                        builder = factory.newDocumentBuilder();
287
                        if (folder.getChildren().length > 0) {
288
                            data = FileUtil.toFileObject(FileUtil.normalizeFile(new File(fn)));
289
                            InputStream is = data.getInputStream();
290
                            document = builder.parse(is);
291
                            is.close();
292
                            lck = data.lock();
293
                            ostm = data.getOutputStream(lck);
294
                            writer = new PrintWriter(new OutputStreamWriter(ostm, "UTF8")); //NOI18N
295
                        }
296
                        // Create or update then write the DOM
297
                        xmlWriter = new XmlWriter(data, sqlHistoryList, writer);
298
                        xmlWriter.write(); // NOI18N
299
                        xmlWriter.write(xmlWriter.removeElements(document), ""); // NOI18N
300
                        break;
301
                }
302
            } catch (ParserConfigurationException ex) {
303
                LOGGER.log(Level.INFO, ex.getMessage());
304
                throw new IOException(ex.getLocalizedMessage(), ex);
305
306
            } catch (SAXException ex) {
307
                LOGGER.log(Level.INFO, ex.getMessage());
308
                throw new IOException(ex.getLocalizedMessage(),ex);
309
            } finally {
310
                if (writer != null) {
311
                    writer.flush();
312
                    writer.close();
313
                    writer = null;
314
                }
315
                if (ostm != null) {
316
                    ostm.close();
317
                    ostm = null;
318
                }
319
                if (lck != null) {
320
                    lck.releaseLock();
321
                }
322
            }
323
        }
324
    }
325
326
    private static final class XmlWriter {
327
        private PrintWriter pw;
328
        private List<SQLHistory> sqlHistoryList;
329
330
        public XmlWriter(FileObject data, List<SQLHistory> sqlHistoryList, PrintWriter pw) {
331
            this.sqlHistoryList = sqlHistoryList;
332
            this.pw = pw;
333
        }
334
335
        /**
336
         * 
337
         * create XML elements from SQL statements
338
         */
339
        private Node createElements(Document document) {
340
            Element newNode = null;
341
            Element nameNode = null;
342
            if (null == document.getDocumentElement()) {
343
                newNode = document.createElement("history");  // NOI18N
344
                for (SQLHistory sqlHistory : sqlHistoryList) {
345
                    nameNode = document.createElement("sql");  // NOI18N
346
                    nameNode.appendChild(document.createTextNode(sqlHistory.getSql()));
347
                    nameNode.setAttribute("url", sqlHistory.getUrl());  // NOI18N
348
                    nameNode.setAttribute("date", new Long(sqlHistory.getDate().getTime()).toString());  // NOI18N
349
                    newNode.appendChild(nameNode);
350
                }
351
                document.adoptNode(newNode);
352
            } else {
353
                newNode = document.getDocumentElement();
354
                for (SQLHistory sqlHistory : sqlHistoryList) {
355
                    nameNode = document.createElement("sql");  // NOI18N
356
                    nameNode.appendChild(document.createTextNode(sqlHistory.getSql()));
357
                    nameNode.setAttribute("url", sqlHistory.getUrl());  // NOI18N
358
                    nameNode.setAttribute("date", new Long(sqlHistory.getDate().getTime()).toString());  // NOI18N
359
                    newNode.insertBefore(nameNode, newNode.getFirstChild());
360
                }
361
            }
362
            return newNode;
363
        }
364
365
        /**
366
         * 
367
         * remove XML elements when the number of statements to save is reduced in the SQL History dialog   
368
         */
369
        private Node removeElements(Document document) {
370
            NodeList nodes = null;
371
            Element history = document.getDocumentElement();
372
            if (null != history) {
373
                nodes = history.getElementsByTagName("sql");
374
                int elemsToRemove = SQLHistoryPersistenceManager.getInstance().getNumElemsToRemove();
375
                // Statements to save was set to 0                   
376
                if (elemsToRemove == 0) {
377
                    for (int i = 0; i < nodes.getLength(); i++) {
378
                        if (nodes.item(0) != null) {
379
                            history.removeChild(nodes.item(0));
380
                        }
381
                    }
382
                }
383
                // Remove elements from the DOM
384
                for (int i = 0; i < elemsToRemove; i++) {
385
                    if (nodes.item(0) != null) {
386
                        history.removeChild(nodes.item(nodes.getLength() - 1));
387
                    }
388
                }
389
            }
390
            return history;
391
        }
392
393
        private void write() {
394
            pw.println("<?xml version='1.0' encoding='UTF-8' ?>");
395
        }
396
397
        /**
398
         * 
399
         * write the SQL statements as xml
400
         */
401
        private void write(Node node, String indent) {
402
            switch (node.getNodeType()) {
403
                case Node.DOCUMENT_NODE: {
404
                    Document doc = (Document) node;
405
                    pw.println(indent + "<?xml version='1.0'?>");  // NOI18N
406
                    Node child = doc.getFirstChild();
407
                    while (child != null) {
408
                        write(child, indent);
409
                        child = child.getNextSibling();
410
                    }
411
                    break;
412
                }
413
                case Node.ELEMENT_NODE: {
414
                    Element elt = (Element) node;
415
                    pw.print(indent + "<" + elt.getTagName());
416
                    NamedNodeMap attrs = elt.getAttributes();
417
                    for (int i = 0; i < attrs.getLength(); i++) {
418
                        Node a = attrs.item(i);
419
                        pw.print(" " + a.getNodeName() + "='" + fixup(a.getNodeValue()) + "'");  // NOI18N
420
                    }
421
                    pw.println(">");  // NOI18N
422
                    String newindent = indent + "    ";  // NOI18N
423
                    Node child = elt.getFirstChild();
424
                    while (child != null) {
425
                        write(child, newindent);
426
                        child = child.getNextSibling();
427
                    }
428
429
                    pw.println(indent + "</" + elt.getTagName() + ">");  // NOI18N
430
                    break;
431
                }
432
                case Node.TEXT_NODE: {
433
                    Text textNode = (Text) node;
434
                    String text = textNode.getData().trim();
435
                    if ((text != null) && text.length() > 0) {
436
                        pw.println(indent + fixup(text));
437
                    }
438
                    break;
439
                }
440
                default:
441
                    LOGGER.log(Level.INFO, "Ignoring node: " + node.getClass().getName());  // NOI18N
442
                    break;
443
            }
444
445
        }
446
447
        private String fixup(String s) {
448
            StringBuilder sb = new StringBuilder();
449
            int len = s.length();
450
            for (int i = 0; i < len; i++) {
451
                char c = s.charAt(i);
452
                switch (c) {
453
                    default:
454
                        sb.append(c);
455
                        break;
456
                    case '<':               // NOI18N
457
                        sb.append("&lt;");  // NOI18N
458
                        break;
459
                    case '>':               // NOI18N
460
                        sb.append("&gt;");  // NOI18N
461
                        break;
462
                    case '&':                // NOI18N
463
                        sb.append("&amp;");  // NOI18N
464
                        break;
465
                    case '"':                 // NOI18N
466
                        sb.append("&quot;");  // NOI18N
467
                        break;
468
                    case '\'':               // NOI18N
469
                        sb.append("&apos;"); // NOI18N
470
                        break;
471
                }
472
            }
473
            return sb.toString();
474
        }
475
    }
476
477
    /**
478
     * SAX handler for reading the XML file.
479
     */
480
    private static final class Handler extends DefaultHandler implements ContentHandler {
481
482
        private static final String ELEMENT_SQL = "sql"; // NOI18N
483
        private static final String ATTR_URL_PROPERTY_VALUE = "url"; // NOI18N
484
        private static final String ATTR_DATE_PROPERTY_VALUE = "date"; // NOI18N
485
        private static String url;
486
        private static StringBuilder sql;
487
        private static Date date;
488
        boolean matchingUrl = false;
489
        private List<SQLHistory> xmlSqlHistoryList = new ArrayList<SQLHistory>();
490
        static boolean isSql = false;
491
        private int limit;
492
        private static Calendar calendar = Calendar.getInstance();
493
        
494
        public Handler(int limit) {
495
            this.limit = limit;
496
        }
497
498
        @Override
499
        public void startElement(String uri, String localName, String qName, Attributes attrs) throws SAXException {
500
            if (ELEMENT_SQL.equals(qName)) {
501
                isSql = true;
502
                url = attrs.getValue(ATTR_URL_PROPERTY_VALUE);
503
                try {
504
                    calendar.setTimeInMillis(Long.parseLong(attrs.getValue(ATTR_DATE_PROPERTY_VALUE)));
505
                    date = calendar.getTime();
506
                } catch (NumberFormatException nfe) {
507
                    // #152486 - previously date stored in text format
508
                    try {
509
                        date = DateFormat.getDateTimeInstance(DateFormat.SHORT, DateFormat.SHORT).parse(attrs.getValue(ATTR_DATE_PROPERTY_VALUE));
510
                    } catch (ParseException pe) {
511
                        // # 152486; Date stored is not parsable, so reset the date to the current timestamp
512
                        date = calendar.getTime();
513
                    }
514
                }
515
            } else {
516
                isSql = false;
517
            }
518
        }
519
520
        @Override
521
        public void endElement(String uri, String localName, String qName) {
522
            if (ELEMENT_SQL.equals(qName)) {
523
                if (url != null && sql != null && date != null) {
524
                    addHistory(url, sql.toString(), date);
525
                    reset();
526
                }
527
            }
528
        }
529
530
        private static void reset() {
531
            // reset data
532
            url = null;
533
            date = null;
534
            sql = null;
535
        }
536
537
        private void addHistory(String url, String sql, Date date) {
538
            if ((xmlSqlHistoryList.size() <= limit) || limit == 0) {
539
                xmlSqlHistoryList.add(new SQLHistory(url, sql, date));
540
                setXmlSqlHistoryList(xmlSqlHistoryList);
541
            } else {
542
                // remove a statement from the end of the list
543
                xmlSqlHistoryList.remove(xmlSqlHistoryList.size() - 1);
544
            }
545
        }
546
547
        @Override
548
        public void characters(char buf[], int offset, int length) {
549
            if (isSql) {
550
                String parsedValue = new String(buf, offset, length);
551
                if (sql == null) {
552
                    sql = new StringBuilder();
553
                    sql.append(parsedValue);
554
                } else {
555
                    sql.append(parsedValue);
556
                }
557
            }
558
        }
559
560
        public void setXmlSqlHistoryList(List<SQLHistory> sqlHistoryList) {
561
            xmlSqlHistoryList = sqlHistoryList;
562
        }
563
564
        public List<SQLHistory> getXmlSqlHistoryList() {
565
            if (xmlSqlHistoryList == null) {
566
                return new ArrayList<SQLHistory>();
567
            } else {
568
                return xmlSqlHistoryList;
569
            }
570
        }
571
    }
572
}
(-)a/db.core/src/org/netbeans/modules/db/sql/history/jaxb.index (+2 lines)
Line 0 Link Here
1
SQLHistory
2
SQLHistoryEntry
(-)a/db.core/test/unit/src/org/netbeans/modules/db/sql/history/SQLHistoryManagerTest.java (-90 / +36 lines)
Lines 41-50 Link Here
41
 */
41
 */
42
package org.netbeans.modules.db.sql.history;
42
package org.netbeans.modules.db.sql.history;
43
43
44
import java.io.File;
45
import java.io.IOException;
44
import java.io.IOException;
46
import java.text.DateFormat;
45
import java.text.DateFormat;
47
import java.text.ParseException;
46
import java.text.ParseException;
47
import java.util.Date;
48
import org.netbeans.junit.NbTestCase;
48
import org.netbeans.junit.NbTestCase;
49
import org.netbeans.junit.NbTestSuite;
49
import org.netbeans.junit.NbTestSuite;
50
import org.openide.filesystems.FileObject;
50
import org.openide.filesystems.FileObject;
Lines 62-69 Link Here
62
 * @author John Baker
62
 * @author John Baker
63
 */
63
 */
64
public class SQLHistoryManagerTest extends NbTestCase {
64
public class SQLHistoryManagerTest extends NbTestCase {
65
65
    public static final String SQL_HISTORY_FOLDER = "Databases/SQLHISTORY"; // NOI18N
66
    public static final String SQL_HISTORY_FOLDER = "Databases/SQLHISTORY"; // NOI18N
66
    public static final String SQL_HISTORY_FILE_NAME = "sql_history.xml";  // NOI18N
67
    public static final String SQL_HISTORY_FILE_NAME = "sql_history.xml";  // NOI18N
68
67
    /** Default constructor.
69
    /** Default constructor.
68
     * @param testName name of particular test case
70
     * @param testName name of particular test case
69
     */
71
     */
Lines 107-213 Link Here
107
    }
109
    }
108
    
110
    
109
    public void testUpdateListRemoveEqualNumber() {
111
    public void testUpdateListRemoveEqualNumber() {
110
        try {
112
        SQLHistoryManager.getInstance().saveSQL(new SQLHistoryEntry("jdbc:// derby", "select * from TRAVEL.TRIP", new Date()));
111
            FileObject root = FileUtil.toFileObject(getWorkDir());
113
        SQLHistoryManager.getInstance().saveSQL(new SQLHistoryEntry("jdbc:// postgres", "select * from TRAVEL.TRIP", new Date()));
112
            // Create a list of SQL statements
114
        SQLHistoryManager.getInstance().setListSize(2);
113
            SQLHistoryManager.getInstance().saveSQL(new SQLHistory("jdbc:// derby", "select * from TRAVEL.TRIP", DateFormat.getInstance().parse("07/10/96 4:5 PM, PDT")));
115
        assertEquals(2, SQLHistoryManager.getInstance().getSQLHistory().size());
114
            SQLHistoryManager.getInstance().saveSQL(new SQLHistory("jdbc:// postgres", "select * from TRAVEL.TRIP", DateFormat.getInstance().parse("07/10/96 4:5 PM, PDT")));
115
            // Save SQL
116
            SQLHistoryManager.getInstance().save(root);
117
            String historyFileRootPath = FileUtil.getFileDisplayName(root) + File.separator + "Databases" + File.separator + "SQLHISTORY";
118
            FileObject historyFileObject = FileUtil.toFileObject(new File(historyFileRootPath));
119
            String historyFilePath = historyFileRootPath + File.separator + SQL_HISTORY_FILE_NAME;
120
            // Limit to 2 SQL statements
121
            SQLHistoryManager.getInstance().updateList(2, historyFilePath , historyFileObject);
122
            assertEquals(0, SQLHistoryManager.getInstance().getSQLHistory().size());
123
        } catch (SQLHistoryException ex) {
124
            Exceptions.printStackTrace(ex);
125
        } catch (IOException ex) {
126
            Exceptions.printStackTrace(ex);
127
        } catch (ParseException ex) {
128
            Exceptions.printStackTrace(ex);
129
        }
130
    }
116
    }
131
    
117
    
132
    public void testUpdateListRemoveLessNumber3() {
118
    public void testUpdateListRemoveLessNumber3() {
133
        try {
119
        SQLHistoryManager.getInstance().setListSize(100);
134
            FileObject root = FileUtil.toFileObject(getWorkDir());
120
        SQLHistoryManager.getInstance().getSQLHistory().clear();
135
            // Create a list of SQL statements
121
            // Create a list of SQL statements
136
            SQLHistoryManager.getInstance().saveSQL(new SQLHistory("jdbc:// derby", "select * from TRAVEL.TRIP", DateFormat.getInstance().parse("07/10/96 4:5 PM, PDT")));
122
        SQLHistoryManager.getInstance().saveSQL(new SQLHistoryEntry("jdbc:// derby", "select * from TRAVEL.TRIP", new Date()));
137
            SQLHistoryManager.getInstance().saveSQL(new SQLHistory("jdbc:// postgres", "select * from TRAVEL.TRIPTYPE", DateFormat.getInstance().parse("07/10/96 4:5 PM, PDT")));
123
        SQLHistoryManager.getInstance().saveSQL(new SQLHistoryEntry("jdbc:// postgres", "select * from TRAVEL.TRIPTYPE", new Date()));
138
            SQLHistoryManager.getInstance().saveSQL(new SQLHistory("jdbc:// postgres", "select * from TRAVEL.TRIP", DateFormat.getInstance().parse("07/10/96 4:5 PM, PDT")));
124
        SQLHistoryManager.getInstance().saveSQL(new SQLHistoryEntry("jdbc:// postgres", "select * from TRAVEL.TRIP", new Date()));
139
            SQLHistoryManager.getInstance().saveSQL(new SQLHistory("jdbc:// postgres", "select * from TRAVEL.TRIP", DateFormat.getInstance().parse("07/10/96 4:5 PM, PDT")));
125
        SQLHistoryManager.getInstance().saveSQL(new SQLHistoryEntry("jdbc:// postgres", "select * from TRAVEL.TRIP", new Date()));
140
            SQLHistoryManager.getInstance().saveSQL(new SQLHistory("jdbc:// postgres", "select * from TRAVEL.PERSON", DateFormat.getInstance().parse("07/10/96 4:5 PM, PDT"))); 
126
        SQLHistoryManager.getInstance().saveSQL(new SQLHistoryEntry("jdbc:// postgres", "select * from TRAVEL.PERSON", new Date()));
141
            assertEquals(5, SQLHistoryManager.getInstance().getSQLHistory().size());
127
        assertEquals(4, SQLHistoryManager.getInstance().getSQLHistory().size());
142
            // Save SQL
128
        SQLHistoryManager.getInstance().setListSize(3);
143
            SQLHistoryManager.getInstance().save(root);
129
        assertEquals(3, SQLHistoryManager.getInstance().getSQLHistory().size());
144
            String historyFilePath = FileUtil.getFileDisplayName(root) + File.separator + "Databases" + File.separator + "SQLHISTORY";
145
            FileObject historyFileObject = root.getFileObject(SQL_HISTORY_FOLDER);
146
            // Limit to 3 SQL statements
147
            SQLHistoryPersistenceManager.getInstance().updateSQLSaved(3, historyFileObject);
148
            assertEquals(3, SQLHistoryPersistenceManager.getInstance().retrieve(historyFileObject).size());
149
        } catch (SQLHistoryException ex) {
150
            Exceptions.printStackTrace(ex);
151
        } catch (IOException ex) {
152
            Exceptions.printStackTrace(ex);
153
        } catch (ClassNotFoundException ex) {
154
            Exceptions.printStackTrace(ex);
155
        } catch (ParseException ex) {
156
            Exceptions.printStackTrace(ex);
157
        }
158
    }
130
    }
159
    
131
    
160
    public void testUpdateListRemoveLessNumber1() {
132
    public void testUpdateListRemoveLessNumber1() {
161
        try {
133
        SQLHistoryManager.getInstance().setListSize(100);
162
            FileObject root = FileUtil.toFileObject(getWorkDir());
134
        SQLHistoryManager.getInstance().getSQLHistory().clear();
163
            // Create a list of SQL statements
135
            // Create a list of SQL statements
164
            SQLHistoryManager.getInstance().saveSQL(new SQLHistory("jdbc:// derby", "select * from TRAVEL.TRIP", DateFormat.getInstance().parse("07/10/96 4:5 PM, PDT")));
136
        SQLHistoryManager.getInstance().saveSQL(new SQLHistoryEntry("jdbc:// derby", "select * from TRAVEL.TRIP", new Date()));
165
            SQLHistoryManager.getInstance().saveSQL(new SQLHistory("jdbc:// postgres1", "select * from TRAVEL.TRIP", DateFormat.getInstance().parse("07/10/96 4:5 PM, PDT")));
137
        SQLHistoryManager.getInstance().saveSQL(new SQLHistoryEntry("jdbc:// postgres1", "select * from TRAVEL.TRIP", new Date()));
166
            SQLHistoryManager.getInstance().saveSQL(new SQLHistory("jdbc:// postgres2", "select * from TRAVEL.TRIP", DateFormat.getInstance().parse("07/10/96 4:5 PM, PDT")));
138
        SQLHistoryManager.getInstance().saveSQL(new SQLHistoryEntry("jdbc:// postgres2", "select * from TRAVEL.TRIP", new Date()));
167
            SQLHistoryManager.getInstance().saveSQL(new SQLHistory("jdbc:// postgres3", "select * from TRAVEL.TRIP", DateFormat.getInstance().parse("07/10/96 4:5 PM, PDT")));
139
        SQLHistoryManager.getInstance().saveSQL(new SQLHistoryEntry("jdbc:// postgres3", "select * from TRAVEL.TRIP", new Date()));
168
            SQLHistoryManager.getInstance().saveSQL(new SQLHistory("jdbc:// postgres4", "select * from TRAVEL.TRIP", DateFormat.getInstance().parse("07/10/96 4:5 PM, PDT"))); 
140
        SQLHistoryManager.getInstance().saveSQL(new SQLHistoryEntry("jdbc:// postgres4", "select * from TRAVEL.TRIP", new Date()));
169
            // Save SQL
141
        assertEquals(5, SQLHistoryManager.getInstance().getSQLHistory().size());
170
            SQLHistoryManager.getInstance().save(root);
142
        SQLHistoryManager.getInstance().setListSize(1);
171
            String historyFilePath = FileUtil.getFileDisplayName(root) + File.separator + "Databases" + File.separator + "SQLHISTORY";
172
            FileObject historyFileObject = FileUtil.toFileObject(new File(historyFilePath));
173
            // Limit to 1 SQL statement
174
            SQLHistoryManager.getInstance().updateList(1, historyFilePath , historyFileObject);
175
            assertEquals(1, SQLHistoryManager.getInstance().getSQLHistory().size());      
143
            assertEquals(1, SQLHistoryManager.getInstance().getSQLHistory().size());      
176
        } catch (SQLHistoryException ex) {
177
            Exceptions.printStackTrace(ex);
178
        } catch (IOException ex) {
179
            Exceptions.printStackTrace(ex);
180
        } catch (ParseException ex) {
181
            Exceptions.printStackTrace(ex);
182
        }
183
    }
144
    }
184
    
145
    
185
      public void testUpdateListRemoveAll() {
146
      public void testUpdateListRemoveAll() {
186
        try {
147
        SQLHistoryManager.getInstance().setListSize(100);
187
            FileObject root = FileUtil.toFileObject(getWorkDir());
148
        SQLHistoryManager.getInstance().getSQLHistory().clear();
188
            // Create a list of SQL statements
149
            // Create a list of SQL statements
189
            SQLHistoryManager.getInstance().saveSQL(new SQLHistory("jdbc:// derby", "select * from TRAVEL.TRIP", DateFormat.getInstance().parse("07/10/96 4:5 PM, PDT")));
150
        SQLHistoryManager.getInstance().saveSQL(new SQLHistoryEntry("jdbc:// derby", "select * from TRAVEL.TRIP", new Date()));
190
            SQLHistoryManager.getInstance().saveSQL(new SQLHistory("jdbc:// postgres1", "select * from TRAVEL.TRIP", DateFormat.getInstance().parse("07/10/96 4:5 PM, PDT")));
151
        SQLHistoryManager.getInstance().saveSQL(new SQLHistoryEntry("jdbc:// postgres1", "select * from TRAVEL.TRIP", new Date()));
191
            SQLHistoryManager.getInstance().saveSQL(new SQLHistory("jdbc:// postgres2", "select * from TRAVEL.TRIP", DateFormat.getInstance().parse("07/10/96 4:5 PM, PDT")));
152
        SQLHistoryManager.getInstance().saveSQL(new SQLHistoryEntry("jdbc:// postgres2", "select * from TRAVEL.TRIP", new Date()));
192
            SQLHistoryManager.getInstance().saveSQL(new SQLHistory("jdbc:// postgres3", "select * from TRAVEL.TRIP", DateFormat.getInstance().parse("07/10/96 4:5 PM, PDT")));
153
        SQLHistoryManager.getInstance().saveSQL(new SQLHistoryEntry("jdbc:// postgres3", "select * from TRAVEL.TRIP", new Date()));
193
            SQLHistoryManager.getInstance().saveSQL(new SQLHistory("jdbc:// postgres4", "select * from TRAVEL.TRIP", DateFormat.getInstance().parse("07/10/96 4:6 PM, PDT"))); 
154
        SQLHistoryManager.getInstance().saveSQL(new SQLHistoryEntry("jdbc:// postgres4", "select * from TRAVEL.TRIP", new Date()));
194
             // Save SQL
155
        assertEquals(5, SQLHistoryManager.getInstance().getSQLHistory().size());
195
            SQLHistoryManager.getInstance().save(root);
156
        SQLHistoryManager.getInstance().setListSize(0);
196
            String historyFilePath = FileUtil.getFileDisplayName(root) + File.separator + "Databases" + File.separator + "SQLHISTORY";
157
        assertEquals(0, SQLHistoryManager.getInstance().getSQLHistory().size());
197
            FileObject historyFileObject = FileUtil.toFileObject(new File(historyFilePath));            
198
            // Limit to 0 SQL statements
199
            SQLHistoryManager.getInstance().updateList(0, historyFilePath, historyFileObject);
200
            SQLHistoryPersistenceManager.getInstance().updateSQLSaved(0, historyFileObject);
201
            assertEquals(0, SQLHistoryPersistenceManager.getInstance().retrieve(historyFileObject).size());                        
202
        } catch (SQLHistoryException ex) {
203
            Exceptions.printStackTrace(ex);
204
        } catch (IOException ex) {
205
            Exceptions.printStackTrace(ex);
206
        } catch (ClassNotFoundException ex) {
207
            Exceptions.printStackTrace(ex);
208
        }  catch (ParseException ex) {
209
            Exceptions.printStackTrace(ex);
210
        }
211
    }
158
    }
212
    
213
}
159
}
(-)a/db.core/test/unit/src/org/netbeans/modules/db/sql/history/SQLHistoryPersistenceManagerTest.java (-19 / +31 lines)
Lines 50-55 Link Here
50
import org.netbeans.junit.NbTestCase;
50
import org.netbeans.junit.NbTestCase;
51
import org.openide.filesystems.FileObject;
51
import org.openide.filesystems.FileObject;
52
import org.openide.filesystems.FileUtil;
52
import org.openide.filesystems.FileUtil;
53
import org.openide.util.Exceptions;
53
54
54
/**
55
/**
55
 * @author John Baker, Jiri Skrivanek
56
 * @author John Baker, Jiri Skrivanek
Lines 77-106 Link Here
77
78
78
    /** Test testExecuteStatements passes if no exceptions occur. */
79
    /** Test testExecuteStatements passes if no exceptions occur. */
79
    public void testExecuteStatements() throws Exception {
80
    public void testExecuteStatements() throws Exception {
80
        List<SQLHistory> sqlHistoryList = new ArrayList<SQLHistory>();
81
        SQLHistoryManager testableManager = new SQLHistoryManager() {
81
        sqlHistoryList.add(new SQLHistory("jdbc:// mysql", "select * from TRAVEL.PERSON", Calendar.getInstance().getTime()));
82
        FileObject fo = FileUtil.toFileObject(getWorkDir());
83
        sqlHistoryList.add(new SQLHistory("jdbc:// oracle", "select * from PERSON", Calendar.getInstance().getTime()));
84
        SQLHistoryPersistenceManager.getInstance().create(fo, sqlHistoryList);
85
    }
86
82
87
    /** Test testMultipleExecutions passes if no exceptions occur. */
83
            @Override
88
    public void testMultipleExecutions() throws Exception {
84
            protected FileObject getConfigRoot() {
89
        List<SQLHistory> sqlHistoryList = new ArrayList<SQLHistory>();
85
                try {
90
        sqlHistoryList.add(new SQLHistory("jdbc:// derby", "select * from TRAVEL.TRIP", Calendar.getInstance().getTime()));
86
                    return FileUtil.toFileObject(getWorkDir());
91
        FileObject fo = FileUtil.toFileObject(getWorkDir());
87
                } catch (IOException ex) {
92
        SQLHistoryPersistenceManager.getInstance().create(fo, sqlHistoryList);
88
                    throw new RuntimeException(ex);
93
        sqlHistoryList.add(new SQLHistory("jdbc:// postgres", "select * from TRAVEL.TRIP", Calendar.getInstance().getTime()));
89
                }
94
        fo = FileUtil.toFileObject(getWorkDir());
90
            }
95
        SQLHistoryPersistenceManager.getInstance().create(fo, sqlHistoryList);
91
92
            @Override
93
            protected String getRelativeHistoryPath() {
94
                return "";
95
            }
96
            
97
        };
98
        testableManager.getSQLHistory().add(new SQLHistoryEntry("jdbc:// mysql", "select * from TRAVEL.PERSON", Calendar.getInstance().getTime()));
99
        testableManager.getSQLHistory().add(new SQLHistoryEntry("jdbc:// oracle", "select * from PERSON", Calendar.getInstance().getTime()));
100
        testableManager.save();
96
    }
101
    }
97
102
98
    /** Tests parsing of date format. */
103
    /** Tests parsing of date format. */
99
    public void testDateParsing() throws Exception {
104
    public void testDateParsing() throws Exception {
100
        URL u = this.getClass().getResource("sql_history.xml");
105
        final URL u = this.getClass().getResource("sql_history.xml");
101
        FileObject fo = FileUtil.toFileObject(new File(u.toURI()));
106
        final FileObject fo = FileUtil.toFileObject(new File(u.toURI()));
102
        List<SQLHistory> sqlHistoryList = SQLHistoryPersistenceManager.getInstance().retrieve(fo.getParent());
107
        SQLHistoryManager testableManager = new SQLHistoryManager() {
103
        for (SQLHistory sqlHistory : sqlHistoryList) {
108
            @Override
109
            protected FileObject getHistoryRoot(boolean create) throws IOException {
110
                return fo;
111
            }
112
        };
113
        
114
        List<SQLHistoryEntry> sqlHistoryList = new ArrayList<SQLHistoryEntry>(testableManager.getSQLHistory());
115
        for (SQLHistoryEntry sqlHistory : sqlHistoryList) {
104
            assertNotNull(sqlHistory.getDate());
116
            assertNotNull(sqlHistory.getDate());
105
        }
117
        }
106
    }
118
    }

Return to bug 204550