Merge branch 'master' of git@github.com:jOOQ/jOOQ.git

This commit is contained in:
Lukas Eder 2012-05-01 22:15:43 +02:00
commit 68f2f11fb6
9 changed files with 685 additions and 105 deletions

View File

@ -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;
}
}

View File

@ -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>();

View File

@ -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));
}
}

View File

@ -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);
}
}

View File

@ -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;
}
}

View File

@ -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());
}
}

View File

@ -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