Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Merge branch 'master' of git@github.com:jOOQ/jOOQ.git
  • Loading branch information
lukaseder committed May 1, 2012
2 parents b71d7b4 + 2970045 commit 68f2f11
Show file tree
Hide file tree
Showing 9 changed files with 684 additions and 104 deletions.
142 changes: 38 additions & 104 deletions jOOQ-console/src/main/java/org/jooq/debug/StatementMatcher.java
Expand Up @@ -39,135 +39,69 @@
import java.io.Serializable; import java.io.Serializable;
import java.util.EnumSet; import java.util.EnumSet;
import java.util.Set; import java.util.Set;
import java.util.regex.Pattern;
import org.jooq.debug.console.misc.TextMatcher;


@SuppressWarnings("serial") @SuppressWarnings("serial")
public class StatementMatcher implements Serializable { public class StatementMatcher implements Serializable {


public static enum TextMatchingType { private boolean isActive;
STARTS_WITH, private TextMatcher threadNameTextMatcher;
CONTAINS, private TextMatcher statementTextMatcher;
EQUALS,
MATCHES_REG_EXP,
}

private String threadName;
private TextMatchingType textMatchingType;
private String text;
private boolean isTextMatchingCaseSensitive;
private Set<SqlQueryType> queryTypeSet; private Set<SqlQueryType> queryTypeSet;


private Pattern pattern;

/** /**
* @param threadName a name or null for no matching on thread name. * @param threadNameTextMatcher a text matcher for thread name or null for no text matching.
* @param textMatchingType a type 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. * @param queryTypeSet some types or null for all types.
*/ */
public StatementMatcher(String threadName, TextMatchingType textMatchingType, String text, boolean isTextMatchingCaseSensitive, Set<SqlQueryType> queryTypeSet) { public StatementMatcher(TextMatcher threadNameTextMatcher, TextMatcher statementTextMatcher, Set<SqlQueryType> queryTypeSet, boolean isActive) {
this.threadName = threadName; this.threadNameTextMatcher = threadNameTextMatcher;
this.textMatchingType = textMatchingType; this.statementTextMatcher = statementTextMatcher;
this.text = text;
this.isTextMatchingCaseSensitive = isTextMatchingCaseSensitive;
this.queryTypeSet = queryTypeSet == null? null: EnumSet.copyOf(queryTypeSet); this.queryTypeSet = queryTypeSet == null? null: EnumSet.copyOf(queryTypeSet);
switch (textMatchingType) { this.isActive = isActive;
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;
}
}
} }


public boolean matches(StatementInfo statementInfo) { public boolean matches(StatementInfo statementInfo) {
if(threadName != null) { if(!isActive) {
if(!threadName.equals(statementInfo.getThreadName())) { return false;
}
boolean hasMatcher = false;
if(threadNameTextMatcher != null) {
if(!threadNameTextMatcher.matches(statementInfo.getThreadName())) {
return false; return false;
} }
hasMatcher = true;
} }
if(textMatchingType != null) { if(statementTextMatcher != null) {
if(text == null) { if(!statementTextMatcher.matches(statementInfo.getQueries())) {
return false; return false;
} }
switch(textMatchingType) { hasMatcher = true;
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;
}
}
}
} }
if(queryTypeSet != null) { if(queryTypeSet != null) {
if(!queryTypeSet.contains(statementInfo.getQueryType())) { if(!queryTypeSet.contains(statementInfo.getQueryType())) {
return false; 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;
}


} }
24 changes: 24 additions & 0 deletions jOOQ-console/src/main/java/org/jooq/debug/console/LoggerPane.java
Expand Up @@ -101,6 +101,7 @@
import org.jooq.debug.QueryLoggingData; import org.jooq.debug.QueryLoggingData;
import org.jooq.debug.ResultSetLoggingData; import org.jooq.debug.ResultSetLoggingData;
import org.jooq.debug.SqlQueryType; import org.jooq.debug.SqlQueryType;
import org.jooq.debug.StatementMatcher;
import org.jooq.debug.console.misc.JTableX; import org.jooq.debug.console.misc.JTableX;
import org.jooq.debug.console.misc.RichTextTransferable; import org.jooq.debug.console.misc.RichTextTransferable;
import org.jooq.debug.console.misc.Utils; import org.jooq.debug.console.misc.Utils;
Expand Down Expand Up @@ -141,6 +142,7 @@ public class LoggerPane extends JPanel {
private JLabel loggerStatusLabel; private JLabel loggerStatusLabel;
private JButton loggerOnButton; private JButton loggerOnButton;
private JButton loggerOffButton; private JButton loggerOffButton;
private JButton statementMatcherButton;
private boolean isLogging; private boolean isLogging;
private boolean isReadQueryTypeDisplayed = true; private boolean isReadQueryTypeDisplayed = true;
private boolean isWriteQueryTypeDisplayed = true; private boolean isWriteQueryTypeDisplayed = true;
Expand Down Expand Up @@ -180,6 +182,19 @@ public void actionPerformed(ActionEvent e) {
} }
}); });
loggerHeaderWestPanel.add(loggerOffButton); 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); loggerHeaderPanel.add(loggerHeaderWestPanel, BorderLayout.WEST);
JPanel loggerHeaderCenterPanel = new JPanel(new FlowLayout(FlowLayout.CENTER, 2, 2)); JPanel loggerHeaderCenterPanel = new JPanel(new FlowLayout(FlowLayout.CENTER, 2, 2));
loggerHeaderCenterPanel.setOpaque(false); loggerHeaderCenterPanel.setOpaque(false);
Expand Down Expand Up @@ -637,6 +652,15 @@ public void run() {
loggerThreadCheckBox.setSelected(false); 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> queryDebuggingInfoList = new ArrayList<QueryDebuggingInfo>();
private List<QueryDebuggingInfo> displayedQueryDebuggingInfoList = new ArrayList<QueryDebuggingInfo>(); private List<QueryDebuggingInfo> displayedQueryDebuggingInfoList = new ArrayList<QueryDebuggingInfo>();
private Map<List<String>, Integer> queriesToCountMap = new HashMap<List<String>, Integer>(); private Map<List<String>, Integer> queriesToCountMap = new HashMap<List<String>, Integer>();
Expand Down
@@ -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 comments on commit 68f2f11

Please sign in to comment.