Merge branch 'master' of git@github.com:jOOQ/jOOQ.git
This commit is contained in:
commit
68f2f11fb6
@ -39,135 +39,69 @@ package org.jooq.debug;
|
||||
import java.io.Serializable;
|
||||
import java.util.EnumSet;
|
||||
import java.util.Set;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import org.jooq.debug.console.misc.TextMatcher;
|
||||
|
||||
@SuppressWarnings("serial")
|
||||
public class StatementMatcher implements Serializable {
|
||||
|
||||
public static enum TextMatchingType {
|
||||
STARTS_WITH,
|
||||
CONTAINS,
|
||||
EQUALS,
|
||||
MATCHES_REG_EXP,
|
||||
}
|
||||
|
||||
private String threadName;
|
||||
private TextMatchingType textMatchingType;
|
||||
private String text;
|
||||
private boolean isTextMatchingCaseSensitive;
|
||||
private boolean isActive;
|
||||
private TextMatcher threadNameTextMatcher;
|
||||
private TextMatcher statementTextMatcher;
|
||||
private Set<SqlQueryType> queryTypeSet;
|
||||
|
||||
private Pattern pattern;
|
||||
|
||||
/**
|
||||
* @param threadName a name or null for no matching on thread name.
|
||||
* @param textMatchingType a type or null for no text matching.
|
||||
* @param threadNameTextMatcher a text matcher for thread name or null for no text matching.
|
||||
* @param statementTextMatcher a text matcher for statement or null for no text matching.
|
||||
* @param queryTypeSet some types or null for all types.
|
||||
*/
|
||||
public StatementMatcher(String threadName, TextMatchingType textMatchingType, String text, boolean isTextMatchingCaseSensitive, Set<SqlQueryType> queryTypeSet) {
|
||||
this.threadName = threadName;
|
||||
this.textMatchingType = textMatchingType;
|
||||
this.text = text;
|
||||
this.isTextMatchingCaseSensitive = isTextMatchingCaseSensitive;
|
||||
public StatementMatcher(TextMatcher threadNameTextMatcher, TextMatcher statementTextMatcher, Set<SqlQueryType> queryTypeSet, boolean isActive) {
|
||||
this.threadNameTextMatcher = threadNameTextMatcher;
|
||||
this.statementTextMatcher = statementTextMatcher;
|
||||
this.queryTypeSet = queryTypeSet == null? null: EnumSet.copyOf(queryTypeSet);
|
||||
switch (textMatchingType) {
|
||||
case CONTAINS: {
|
||||
String patternText = ".*\\Q" + text.replace("\\E", "\\\\E").replace("\\Q", "\\\\Q") + "\\E.*\\Q";
|
||||
pattern = Pattern.compile(patternText, isTextMatchingCaseSensitive? 0: Pattern.CASE_INSENSITIVE);
|
||||
break;
|
||||
}
|
||||
case MATCHES_REG_EXP: {
|
||||
pattern = Pattern.compile(text, isTextMatchingCaseSensitive? 0: Pattern.CASE_INSENSITIVE);
|
||||
break;
|
||||
}
|
||||
}
|
||||
this.isActive = isActive;
|
||||
}
|
||||
|
||||
public boolean matches(StatementInfo statementInfo) {
|
||||
if(threadName != null) {
|
||||
if(!threadName.equals(statementInfo.getThreadName())) {
|
||||
return false;
|
||||
}
|
||||
if(!isActive) {
|
||||
return false;
|
||||
}
|
||||
if(textMatchingType != null) {
|
||||
if(text == null) {
|
||||
boolean hasMatcher = false;
|
||||
if(threadNameTextMatcher != null) {
|
||||
if(!threadNameTextMatcher.matches(statementInfo.getThreadName())) {
|
||||
return false;
|
||||
}
|
||||
switch(textMatchingType) {
|
||||
case STARTS_WITH: {
|
||||
boolean isMatching = false;
|
||||
for(String sql: statementInfo.getQueries()) {
|
||||
if(isTextMatchingCaseSensitive) {
|
||||
if(sql.startsWith(text)) {
|
||||
isMatching = true;
|
||||
break;
|
||||
}
|
||||
} else if(sql.length() >= text.length()) {
|
||||
// Let's avoid creating new String instance.
|
||||
if(sql.substring(0, text.length()).equalsIgnoreCase(text)) {
|
||||
isMatching = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if(!isMatching) {
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case EQUALS: {
|
||||
boolean isMatching = false;
|
||||
for(String sql: statementInfo.getQueries()) {
|
||||
if(isTextMatchingCaseSensitive) {
|
||||
if(sql.equals(text)) {
|
||||
isMatching = true;
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
if(sql.equalsIgnoreCase(text)) {
|
||||
isMatching = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if(!isMatching) {
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case CONTAINS: {
|
||||
boolean isMatching = false;
|
||||
for(String sql: statementInfo.getQueries()) {
|
||||
if(pattern.matcher(sql).matches()) {
|
||||
isMatching = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(!isMatching) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
case MATCHES_REG_EXP: {
|
||||
boolean isMatching = false;
|
||||
for(String sql: statementInfo.getQueries()) {
|
||||
if(pattern.matcher(sql).matches()) {
|
||||
isMatching = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(!isMatching) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
hasMatcher = true;
|
||||
}
|
||||
if(statementTextMatcher != null) {
|
||||
if(!statementTextMatcher.matches(statementInfo.getQueries())) {
|
||||
return false;
|
||||
}
|
||||
hasMatcher = true;
|
||||
}
|
||||
if(queryTypeSet != null) {
|
||||
if(!queryTypeSet.contains(statementInfo.getQueryType())) {
|
||||
return false;
|
||||
}
|
||||
hasMatcher = true;
|
||||
}
|
||||
return true;
|
||||
return hasMatcher;
|
||||
}
|
||||
|
||||
public TextMatcher getThreadNameTextMatcher() {
|
||||
return threadNameTextMatcher;
|
||||
}
|
||||
|
||||
public TextMatcher getStatementTextMatcher() {
|
||||
return statementTextMatcher;
|
||||
}
|
||||
|
||||
public Set<SqlQueryType> getQueryTypeSet() {
|
||||
return queryTypeSet;
|
||||
}
|
||||
|
||||
public boolean isActive() {
|
||||
return isActive;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -101,6 +101,7 @@ import org.jooq.debug.LoggingListener;
|
||||
import org.jooq.debug.QueryLoggingData;
|
||||
import org.jooq.debug.ResultSetLoggingData;
|
||||
import org.jooq.debug.SqlQueryType;
|
||||
import org.jooq.debug.StatementMatcher;
|
||||
import org.jooq.debug.console.misc.JTableX;
|
||||
import org.jooq.debug.console.misc.RichTextTransferable;
|
||||
import org.jooq.debug.console.misc.Utils;
|
||||
@ -141,6 +142,7 @@ public class LoggerPane extends JPanel {
|
||||
private JLabel loggerStatusLabel;
|
||||
private JButton loggerOnButton;
|
||||
private JButton loggerOffButton;
|
||||
private JButton statementMatcherButton;
|
||||
private boolean isLogging;
|
||||
private boolean isReadQueryTypeDisplayed = true;
|
||||
private boolean isWriteQueryTypeDisplayed = true;
|
||||
@ -180,6 +182,19 @@ public class LoggerPane extends JPanel {
|
||||
}
|
||||
});
|
||||
loggerHeaderWestPanel.add(loggerOffButton);
|
||||
statementMatcherButton = new JButton();
|
||||
statementMatcherButton.setOpaque(false);
|
||||
statementMatcherButton.setFocusable(false);
|
||||
statementMatcherButton.setToolTipText("Filter incoming statements");
|
||||
adjustStatementMatcherButton();
|
||||
statementMatcherButton.addActionListener(new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
new StatementMatcherDialogBox(LoggerPane.this, LoggerPane.this.debugger).setVisible(true);
|
||||
adjustStatementMatcherButton();
|
||||
}
|
||||
});
|
||||
loggerHeaderWestPanel.add(statementMatcherButton);
|
||||
loggerHeaderPanel.add(loggerHeaderWestPanel, BorderLayout.WEST);
|
||||
JPanel loggerHeaderCenterPanel = new JPanel(new FlowLayout(FlowLayout.CENTER, 2, 2));
|
||||
loggerHeaderCenterPanel.setOpaque(false);
|
||||
@ -637,6 +652,15 @@ public class LoggerPane extends JPanel {
|
||||
loggerThreadCheckBox.setSelected(false);
|
||||
}
|
||||
|
||||
private void adjustStatementMatcherButton() {
|
||||
StatementMatcher[] loggingStatementMatchers = LoggerPane.this.debugger.getLoggingStatementMatchers();
|
||||
if(loggingStatementMatchers != null) {
|
||||
statementMatcherButton.setIcon(new ImageIcon(getClass().getResource("/org/jooq/debug/console/resources/FilterOn16.png")));
|
||||
} else {
|
||||
statementMatcherButton.setIcon(new ImageIcon(getClass().getResource("/org/jooq/debug/console/resources/FilterOff16.png")));
|
||||
}
|
||||
}
|
||||
|
||||
private List<QueryDebuggingInfo> queryDebuggingInfoList = new ArrayList<QueryDebuggingInfo>();
|
||||
private List<QueryDebuggingInfo> displayedQueryDebuggingInfoList = new ArrayList<QueryDebuggingInfo>();
|
||||
private Map<List<String>, Integer> queriesToCountMap = new HashMap<List<String>, Integer>();
|
||||
|
||||
@ -0,0 +1,109 @@
|
||||
/**
|
||||
* Copyright (c) 2009-2012, Lukas Eder, lukas.eder@gmail.com
|
||||
* Christopher Deckers, chrriis@gmail.com
|
||||
* All rights reserved.
|
||||
*
|
||||
* This software is licensed to you under the Apache License, Version 2.0
|
||||
* (the "License"); You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* . Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* . Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* . Neither the name "jOOQ" nor the names of its contributors may be
|
||||
* used to endorse or promote products derived from this software without
|
||||
* specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
package org.jooq.debug.console;
|
||||
|
||||
import java.awt.BorderLayout;
|
||||
import java.awt.Component;
|
||||
import java.awt.Container;
|
||||
import java.awt.GridLayout;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
|
||||
import javax.swing.BorderFactory;
|
||||
import javax.swing.JButton;
|
||||
import javax.swing.JDialog;
|
||||
import javax.swing.JPanel;
|
||||
import javax.swing.SwingUtilities;
|
||||
|
||||
import org.jooq.debug.Debugger;
|
||||
import org.jooq.debug.StatementMatcher;
|
||||
|
||||
@SuppressWarnings("serial")
|
||||
public class StatementMatcherDialogBox extends JDialog {
|
||||
|
||||
public StatementMatcherDialogBox(Component parent, final Debugger debugger) {
|
||||
super(SwingUtilities.getWindowAncestor(parent), "Statement filters", ModalityType.DOCUMENT_MODAL);
|
||||
setDefaultCloseOperation(DISPOSE_ON_CLOSE);
|
||||
Container contentPane = getContentPane();
|
||||
final StatementMatchersPane statementMatchersPane = new StatementMatchersPane(debugger.getLoggingStatementMatchers());
|
||||
contentPane.add(statementMatchersPane, BorderLayout.CENTER);
|
||||
JPanel buttonBar = new JPanel(new BorderLayout());
|
||||
buttonBar.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
|
||||
JPanel filterButtonsPane = new JPanel(new GridLayout(1, 2, 2, 0));
|
||||
JButton addFilterButton = new JButton("Add filter");
|
||||
addFilterButton.addActionListener(new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
statementMatchersPane.addStatementMatcherPane(new StatementMatcherPane(statementMatchersPane, null));
|
||||
}
|
||||
});
|
||||
filterButtonsPane.add(addFilterButton);
|
||||
JButton removeAllFiltersButton = new JButton("Remove all");
|
||||
removeAllFiltersButton.addActionListener(new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
statementMatchersPane.removeAllStatementMatcherPanes();
|
||||
}
|
||||
});
|
||||
filterButtonsPane.add(removeAllFiltersButton);
|
||||
buttonBar.add(filterButtonsPane, BorderLayout.WEST);
|
||||
JPanel rightButtonsPane = new JPanel(new GridLayout(1, 2, 2, 0));
|
||||
JButton okButton = new JButton("OK");
|
||||
okButton.addActionListener(new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
StatementMatcher[] statementMatchers = statementMatchersPane.getStatementMatchers();
|
||||
debugger.setLoggingStatementMatchers(statementMatchers.length == 0? null: statementMatchers);
|
||||
dispose();
|
||||
}
|
||||
});
|
||||
rightButtonsPane.add(okButton);
|
||||
JButton cancelButton = new JButton("Cancel");
|
||||
cancelButton.addActionListener(new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
dispose();
|
||||
}
|
||||
});
|
||||
rightButtonsPane.add(cancelButton);
|
||||
buttonBar.add(rightButtonsPane, BorderLayout.EAST);
|
||||
contentPane.add(buttonBar, BorderLayout.SOUTH);
|
||||
setSize(600, 400);
|
||||
setLocationRelativeTo(SwingUtilities.getWindowAncestor(parent));
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,157 @@
|
||||
/**
|
||||
* Copyright (c) 2009-2012, Lukas Eder, lukas.eder@gmail.com
|
||||
* Christopher Deckers, chrriis@gmail.com
|
||||
* All rights reserved.
|
||||
*
|
||||
* This software is licensed to you under the Apache License, Version 2.0
|
||||
* (the "License"); You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* . Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* . Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* . Neither the name "jOOQ" nor the names of its contributors may be
|
||||
* used to endorse or promote products derived from this software without
|
||||
* specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
package org.jooq.debug.console;
|
||||
|
||||
import java.awt.GridBagConstraints;
|
||||
import java.awt.GridBagLayout;
|
||||
import java.awt.Insets;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
import java.util.ArrayList;
|
||||
import java.util.EnumSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.swing.BorderFactory;
|
||||
import javax.swing.ImageIcon;
|
||||
import javax.swing.JButton;
|
||||
import javax.swing.JCheckBox;
|
||||
import javax.swing.JPanel;
|
||||
import javax.swing.JToolBar;
|
||||
|
||||
import org.jooq.debug.SqlQueryType;
|
||||
import org.jooq.debug.StatementMatcher;
|
||||
import org.jooq.debug.console.misc.TextMatcher;
|
||||
|
||||
@SuppressWarnings("serial")
|
||||
public class StatementMatcherPane extends JPanel {
|
||||
|
||||
private JCheckBox activeCheckBox;
|
||||
private JCheckBox threadNameTextMatcherCheckBox;
|
||||
private TextMatcherPane threadNameTextMatcherPane;
|
||||
private JCheckBox statementTextMatcherCheckBox;
|
||||
private TextMatcherPane statementTextMatcherPane;
|
||||
private JCheckBox statementTypeCheckBox;
|
||||
private JCheckBox statementTypeSelectCheckBox;
|
||||
private JCheckBox statementTypeUpdateCheckBox;
|
||||
private JCheckBox statementTypeInsertCheckBox;
|
||||
private JCheckBox statementTypeDeleteCheckBox;
|
||||
private JCheckBox statementTypeOtherCheckBox;
|
||||
|
||||
public StatementMatcherPane(final StatementMatchersPane statementMatchersPane, StatementMatcher statementMatcher) {
|
||||
super(new GridBagLayout());
|
||||
setBorder(BorderFactory.createLineBorder(getBackground().darker()));
|
||||
if(statementMatcher == null) {
|
||||
statementMatcher = new StatementMatcher(null, null, null, true);
|
||||
}
|
||||
int y = 0;
|
||||
JPanel northPane = new JPanel(new GridBagLayout());
|
||||
activeCheckBox = new JCheckBox("Active", statementMatcher.isActive());
|
||||
northPane.add(activeCheckBox, new GridBagConstraints(0, 0, 1, 1, 1, 0, GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL, new Insets(0, 0, 0, 0), 0, 0));
|
||||
JToolBar closeButtonPane = new JToolBar();
|
||||
closeButtonPane.setFloatable(false);
|
||||
JButton closeButton = new JButton(new ImageIcon(getClass().getResource("/org/jooq/debug/console/resources/TabCloseActive14.png")));
|
||||
closeButton.setFocusable(false);
|
||||
closeButton.addActionListener(new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
statementMatchersPane.removeStatementMatcherPane(StatementMatcherPane.this);
|
||||
}
|
||||
});
|
||||
closeButtonPane.add(closeButton);
|
||||
northPane.add(closeButtonPane, new GridBagConstraints(1, 0, 1, 1, 0, 0, GridBagConstraints.EAST, GridBagConstraints.NONE, new Insets(0, 5, 0, 0), 0, 0));
|
||||
add(northPane, new GridBagConstraints(0, y, 2, 1, 1, 0, GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL, new Insets(0, 0, 0, 0), 0, 0));
|
||||
y++;
|
||||
TextMatcher statementTextMatcher = statementMatcher.getStatementTextMatcher();
|
||||
statementTextMatcherCheckBox = new JCheckBox("Statement", statementTextMatcher != null);
|
||||
add(statementTextMatcherCheckBox, new GridBagConstraints(0, y, 1, 1, 0, 0, GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets(0, 0, 0, 0), 0, 0));
|
||||
statementTextMatcherPane = new TextMatcherPane(statementTextMatcher);
|
||||
add(statementTextMatcherPane, new GridBagConstraints(1, y, 1, 1, 1, 0, GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets(0, 5, 0, 0), 0, 0));
|
||||
y++;
|
||||
Set<SqlQueryType> queryTypeSet = statementMatcher.getQueryTypeSet();
|
||||
statementTypeCheckBox = new JCheckBox("Type", queryTypeSet != null);
|
||||
add(statementTypeCheckBox, new GridBagConstraints(0, y, 1, 1, 0, 0, GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets(0, 0, 0, 0), 0, 0));
|
||||
JPanel typesPane = new JPanel(new GridBagLayout());
|
||||
statementTypeSelectCheckBox = new JCheckBox("SELECT", queryTypeSet != null && queryTypeSet.contains(SqlQueryType.SELECT));
|
||||
typesPane.add(statementTypeSelectCheckBox, new GridBagConstraints(0, 0, 1, 1, 0, 0, GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets(0, 0, 0, 0), 0, 0));
|
||||
statementTypeUpdateCheckBox = new JCheckBox("UPDATE", queryTypeSet != null && queryTypeSet.contains(SqlQueryType.UPDATE));
|
||||
typesPane.add(statementTypeUpdateCheckBox, new GridBagConstraints(1, 0, 1, 1, 0, 0, GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets(0, 2, 0, 0), 0, 0));
|
||||
statementTypeInsertCheckBox = new JCheckBox("INSERT", queryTypeSet != null && queryTypeSet.contains(SqlQueryType.INSERT));
|
||||
typesPane.add(statementTypeInsertCheckBox, new GridBagConstraints(2, 0, 1, 1, 0, 0, GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets(0, 2, 0, 0), 0, 0));
|
||||
statementTypeDeleteCheckBox = new JCheckBox("DELETE", queryTypeSet != null && queryTypeSet.contains(SqlQueryType.DELETE));
|
||||
typesPane.add(statementTypeDeleteCheckBox, new GridBagConstraints(3, 0, 1, 1, 0, 0, GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets(0, 2, 0, 0), 0, 0));
|
||||
statementTypeOtherCheckBox = new JCheckBox("OTHER", queryTypeSet != null && queryTypeSet.contains(SqlQueryType.OTHER));
|
||||
typesPane.add(statementTypeOtherCheckBox, new GridBagConstraints(4, 0, 1, 1, 0, 0, GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets(0, 2, 0, 0), 0, 0));
|
||||
add(typesPane, new GridBagConstraints(1, y, 1, 1, 1, 0, GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets(0, 5, 0, 0), 0, 0));
|
||||
y++;
|
||||
TextMatcher threadNameTextMatcher = statementMatcher.getThreadNameTextMatcher();
|
||||
threadNameTextMatcherCheckBox = new JCheckBox("Thread name", threadNameTextMatcher != null);
|
||||
add(threadNameTextMatcherCheckBox, new GridBagConstraints(0, y, 1, 1, 0, 0, GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets(0, 0, 0, 0), 0, 0));
|
||||
threadNameTextMatcherPane = new TextMatcherPane(threadNameTextMatcher);
|
||||
add(threadNameTextMatcherPane, new GridBagConstraints(1, y, 1, 1, 1, 0, GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets(0, 5, 0, 0), 0, 0));
|
||||
}
|
||||
|
||||
public StatementMatcher getStatementMatcher() {
|
||||
boolean isActive = activeCheckBox.isSelected();
|
||||
TextMatcher threadNameTextMatcher = threadNameTextMatcherCheckBox.isSelected()? threadNameTextMatcherPane.getTextMatcher(): null;
|
||||
TextMatcher statementTextMatcher = statementTextMatcherCheckBox.isSelected()? statementTextMatcherPane.getTextMatcher(): null;
|
||||
Set<SqlQueryType> queryTypeSet;
|
||||
if(statementTypeCheckBox.isSelected()) {
|
||||
List<SqlQueryType> typeList = new ArrayList<SqlQueryType>();
|
||||
if(statementTypeSelectCheckBox.isSelected()) {
|
||||
typeList.add(SqlQueryType.SELECT);
|
||||
}
|
||||
if(statementTypeUpdateCheckBox.isSelected()) {
|
||||
typeList.add(SqlQueryType.UPDATE);
|
||||
}
|
||||
if(statementTypeInsertCheckBox.isSelected()) {
|
||||
typeList.add(SqlQueryType.INSERT);
|
||||
}
|
||||
if(statementTypeDeleteCheckBox.isSelected()) {
|
||||
typeList.add(SqlQueryType.DELETE);
|
||||
}
|
||||
if(statementTypeOtherCheckBox.isSelected()) {
|
||||
typeList.add(SqlQueryType.OTHER);
|
||||
}
|
||||
queryTypeSet = EnumSet.copyOf(typeList);
|
||||
} else {
|
||||
queryTypeSet = null;
|
||||
}
|
||||
return new StatementMatcher(threadNameTextMatcher, statementTextMatcher, queryTypeSet, isActive);
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,128 @@
|
||||
/**
|
||||
* Copyright (c) 2009-2012, Lukas Eder, lukas.eder@gmail.com
|
||||
* Christopher Deckers, chrriis@gmail.com
|
||||
* All rights reserved.
|
||||
*
|
||||
* This software is licensed to you under the Apache License, Version 2.0
|
||||
* (the "License"); You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* . Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* . Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* . Neither the name "jOOQ" nor the names of its contributors may be
|
||||
* used to endorse or promote products derived from this software without
|
||||
* specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
package org.jooq.debug.console;
|
||||
|
||||
import java.awt.BorderLayout;
|
||||
import java.awt.Component;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.GridLayout;
|
||||
import java.awt.Rectangle;
|
||||
|
||||
import javax.swing.JPanel;
|
||||
import javax.swing.JScrollPane;
|
||||
import javax.swing.Scrollable;
|
||||
|
||||
import org.jooq.debug.StatementMatcher;
|
||||
|
||||
@SuppressWarnings("serial")
|
||||
public class StatementMatchersPane extends JPanel {
|
||||
|
||||
private static class ScrollablePane extends JPanel implements Scrollable {
|
||||
|
||||
public ScrollablePane() {
|
||||
super(new GridLayout(0, 1, 1, 1));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Dimension getPreferredScrollableViewportSize() {
|
||||
return getPreferredSize();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean getScrollableTracksViewportHeight() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean getScrollableTracksViewportWidth() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getScrollableBlockIncrement(Rectangle visibleRect, int orientation, int direction) {
|
||||
return 100;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getScrollableUnitIncrement(Rectangle visibleRect, int orientation, int direction) {
|
||||
return 10;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private JPanel statementMatcherPanesContainer;
|
||||
|
||||
public StatementMatchersPane(StatementMatcher[] statementMatchers) {
|
||||
super(new BorderLayout());
|
||||
statementMatcherPanesContainer = new ScrollablePane();
|
||||
add(new JScrollPane(statementMatcherPanesContainer), BorderLayout.CENTER);
|
||||
if(statementMatchers != null) {
|
||||
for(StatementMatcher statementMatcher: statementMatchers) {
|
||||
addStatementMatcherPane(new StatementMatcherPane(this, statementMatcher));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void addStatementMatcherPane(StatementMatcherPane statementMatcherPane) {
|
||||
statementMatcherPanesContainer.add(statementMatcherPane);
|
||||
statementMatcherPanesContainer.revalidate();
|
||||
statementMatcherPanesContainer.repaint();
|
||||
statementMatcherPanesContainer.scrollRectToVisible(new Rectangle(0, Short.MAX_VALUE, 1, 1));
|
||||
}
|
||||
|
||||
void removeAllStatementMatcherPanes() {
|
||||
statementMatcherPanesContainer.removeAll();
|
||||
statementMatcherPanesContainer.revalidate();
|
||||
statementMatcherPanesContainer.repaint();
|
||||
}
|
||||
|
||||
void removeStatementMatcherPane(StatementMatcherPane statementMatcherPane) {
|
||||
statementMatcherPanesContainer.remove(statementMatcherPane);
|
||||
statementMatcherPanesContainer.revalidate();
|
||||
statementMatcherPanesContainer.repaint();
|
||||
}
|
||||
|
||||
public StatementMatcher[] getStatementMatchers() {
|
||||
Component[] components = statementMatcherPanesContainer.getComponents();
|
||||
StatementMatcher[] statementMatchers = new StatementMatcher[components.length];
|
||||
for(int i=0; i<components.length; i++) {
|
||||
statementMatchers[i] = ((StatementMatcherPane)components[i]).getStatementMatcher();
|
||||
}
|
||||
return statementMatchers;
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,78 @@
|
||||
/**
|
||||
* Copyright (c) 2009-2012, Lukas Eder, lukas.eder@gmail.com
|
||||
* Christopher Deckers, chrriis@gmail.com
|
||||
* All rights reserved.
|
||||
*
|
||||
* This software is licensed to you under the Apache License, Version 2.0
|
||||
* (the "License"); You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* . Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* . Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* . Neither the name "jOOQ" nor the names of its contributors may be
|
||||
* used to endorse or promote products derived from this software without
|
||||
* specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
package org.jooq.debug.console;
|
||||
|
||||
import java.awt.GridBagConstraints;
|
||||
import java.awt.GridBagLayout;
|
||||
import java.awt.Insets;
|
||||
|
||||
import javax.swing.JCheckBox;
|
||||
import javax.swing.JComboBox;
|
||||
import javax.swing.JPanel;
|
||||
import javax.swing.JTextField;
|
||||
|
||||
import org.jooq.debug.console.misc.TextMatcher;
|
||||
import org.jooq.debug.console.misc.TextMatcher.TextMatchingType;
|
||||
|
||||
|
||||
@SuppressWarnings("serial")
|
||||
public class TextMatcherPane extends JPanel {
|
||||
|
||||
private JComboBox matcherTypeComboBox;
|
||||
private JTextField textField;
|
||||
private JCheckBox caseSensitiveCheckBox;
|
||||
|
||||
public TextMatcherPane(TextMatcher textMatcher) {
|
||||
setLayout(new GridBagLayout());
|
||||
matcherTypeComboBox = new JComboBox(TextMatchingType.values());
|
||||
add(matcherTypeComboBox, new GridBagConstraints(0, 0, 1, 1, 0, 0, GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets(0, 0, 0, 0), 0, 0));
|
||||
textField = new JTextField(14);
|
||||
add(textField, new GridBagConstraints(1, 0, 1, 1, 0, 0, GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets(0, 2, 0, 0), 0, 0));
|
||||
caseSensitiveCheckBox = new JCheckBox("Case sensitive");
|
||||
add(caseSensitiveCheckBox, new GridBagConstraints(2, 0, 1, 1, 0, 0, GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets(0, 2, 0, 0), 0, 0));
|
||||
if(textMatcher != null) {
|
||||
matcherTypeComboBox.setSelectedItem(textMatcher.getType());
|
||||
textField.setText(textMatcher.getText());
|
||||
caseSensitiveCheckBox.setSelected(textMatcher.isCaseSensitive());
|
||||
}
|
||||
}
|
||||
|
||||
public TextMatcher getTextMatcher() {
|
||||
return new TextMatcher((TextMatchingType)matcherTypeComboBox.getSelectedItem(), textField.getText(), caseSensitiveCheckBox.isSelected());
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,150 @@
|
||||
/**
|
||||
* Copyright (c) 2009-2012, Lukas Eder, lukas.eder@gmail.com
|
||||
* Christopher Deckers, chrriis@gmail.com
|
||||
* All rights reserved.
|
||||
*
|
||||
* This software is licensed to you under the Apache License, Version 2.0
|
||||
* (the "License"); You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* . Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* . Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* . Neither the name "jOOQ" nor the names of its contributors may be
|
||||
* used to endorse or promote products derived from this software without
|
||||
* specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
package org.jooq.debug.console.misc;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
@SuppressWarnings("serial")
|
||||
public class TextMatcher implements Serializable {
|
||||
|
||||
public static enum TextMatchingType {
|
||||
STARTS_WITH("Starts with"),
|
||||
CONTAINS("Contains"),
|
||||
EQUALS("Equals"),
|
||||
MATCHES_REG_EXP("Matches Reg. Exp."),
|
||||
;
|
||||
private String name;
|
||||
TextMatchingType(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
@Override
|
||||
public String toString() {
|
||||
return name;
|
||||
}
|
||||
}
|
||||
|
||||
private TextMatchingType type;
|
||||
private String text;
|
||||
private boolean isCaseSensitive;
|
||||
|
||||
private Pattern pattern;
|
||||
|
||||
public TextMatcher(TextMatchingType type, String text, boolean isCaseSensitive) {
|
||||
this.type = type;
|
||||
this.text = text;
|
||||
this.isCaseSensitive = isCaseSensitive;
|
||||
switch (type) {
|
||||
case CONTAINS: {
|
||||
String patternText = ".*\\Q" + text.replace("\\E", "\\\\E").replace("\\Q", "\\\\Q") + "\\E.*\\Q";
|
||||
pattern = Pattern.compile(patternText, isCaseSensitive? Pattern.DOTALL: Pattern.DOTALL | Pattern.CASE_INSENSITIVE);
|
||||
break;
|
||||
}
|
||||
case MATCHES_REG_EXP: {
|
||||
pattern = Pattern.compile(text, isCaseSensitive? Pattern.DOTALL: Pattern.DOTALL | Pattern.CASE_INSENSITIVE);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public boolean matches(String... texts) {
|
||||
if(text == null) {
|
||||
return false;
|
||||
}
|
||||
switch(type) {
|
||||
case STARTS_WITH: {
|
||||
for(String sql: texts) {
|
||||
if(isCaseSensitive) {
|
||||
if(sql.startsWith(text)) {
|
||||
return true;
|
||||
}
|
||||
} else if(sql.length() >= text.length()) {
|
||||
// Let's avoid creating new String instance.
|
||||
if(sql.substring(0, text.length()).equalsIgnoreCase(text)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
case EQUALS: {
|
||||
for(String sql: texts) {
|
||||
if(isCaseSensitive) {
|
||||
if(sql.equals(text)) {
|
||||
return true;
|
||||
}
|
||||
} else {
|
||||
if(sql.equalsIgnoreCase(text)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
case CONTAINS: {
|
||||
for(String sql: texts) {
|
||||
if(pattern.matcher(sql).matches()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
case MATCHES_REG_EXP: {
|
||||
for(String sql: texts) {
|
||||
if(pattern.matcher(sql).matches()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public TextMatchingType getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
public String getText() {
|
||||
return text;
|
||||
}
|
||||
|
||||
public boolean isCaseSensitive() {
|
||||
return isCaseSensitive;
|
||||
}
|
||||
|
||||
}
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 3.6 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 344 B |
Loading…
Reference in New Issue
Block a user