diff --git a/pom.xml b/pom.xml index 0772f93c23..e89d2b6af2 100644 --- a/pom.xml +++ b/pom.xml @@ -99,6 +99,7 @@ org.apache.maven.plugins maven-compiler-plugin + 2.3.2 UTF-8 1.6 @@ -153,7 +154,7 @@ - + + javax.servlet @@ -186,25 +189,10 @@ org.springframework spring - 2.5.6 + 2.0 provided - - - org.apache.ibatis - ibatis-sqlmap - 2.3.4.726 - test - - - + log4j log4j @@ -311,6 +299,12 @@ 0.7.1-rc2 test + + com.jolbox + bonecp-test-commons + 0.7.1-rc2 + test + proxool @@ -332,4 +326,4 @@ test - \ No newline at end of file + diff --git a/src/main/java/com/alibaba/druid/filter/stat/StatFilter.java b/src/main/java/com/alibaba/druid/filter/stat/StatFilter.java index 962f26d047..e72d649710 100644 --- a/src/main/java/com/alibaba/druid/filter/stat/StatFilter.java +++ b/src/main/java/com/alibaba/druid/filter/stat/StatFilter.java @@ -714,14 +714,20 @@ public class StatFilter extends FilterEventAdapter implements StatFilterMBean { } public JdbcSqlStat createSqlStat(StatementProxy statement, String sql) { + + sql = mergeSql(sql); return dataSourceStat.createSqlStat(sql); } public JdbcSqlStat getSqlCounter(String sql) { + + sql = mergeSql(sql); //mergeSql return getSqlStat(sql); } public JdbcSqlStat getSqlStat(String sql) { + + sql = mergeSql(sql); return dataSourceStat.getSqlStat(sql); } diff --git a/src/main/java/com/alibaba/druid/pool/console/DruidConsole.java b/src/main/java/com/alibaba/druid/pool/console/DruidConsole.java deleted file mode 100644 index dea45bb154..0000000000 --- a/src/main/java/com/alibaba/druid/pool/console/DruidConsole.java +++ /dev/null @@ -1,148 +0,0 @@ -package com.alibaba.druid.pool.console; - -import java.io.Console; -import java.io.PrintWriter; -import java.util.ArrayList; -import java.util.List; -import java.util.Map; - -import javax.management.Attribute; -import javax.management.AttributeList; -import javax.management.MBeanAttributeInfo; -import javax.management.MBeanInfo; -import javax.management.ObjectName; - -public class DruidConsole { - - private ProxyClient proxy; - private Console console; - private PrintWriter out; - private List entries = new ArrayList(); - - private DruidConsole(){ - console = System.console(); - out = console.writer(); - } - - public void run() throws Exception { - proxy = ProxyClient.getProxyClient("10.20.133.134", 9006, null, null); - proxy.connect(); - - for (;;) { - String line = console.readLine(); - if ("exit".equals(line)) { - break; - } - - if ("ls".equals(line)) { - ls(line); - } - - if ("desc".equals(line)) { - desc(line); - } - - if (line.startsWith("show ")) { - show(line); - } - } - } - - public void show(String line) throws Exception { - String[] items = line.split(" "); - - DataSourceEntry current; - { - String arg = items[1]; - int index = Integer.parseInt(arg); - current = entries.get(index); - } - - long interval = 0; - { - String tmp = items[2]; - interval = Long.parseLong(tmp); - } - - String[] attributes = new String[] { "CreateCount", "DestroyCount", "ActivePeak", "ActiveCount", "PoolingCount", "CommitCount", "RollbackCount" }; - String[] titles = attributes; - - for (int i = 0; i < titles.length; ++i) { - if (i != 0) { - out.print("\t\t"); - } - out.print(titles[i]); - } - out.println(); - for (int i = 0; i < 10; ++i) { - AttributeList values = proxy.getAttributes(current.getObjectName(), attributes); - for (int j = 0; j < attributes.length; ++j) { - Attribute attribute = (Attribute) values.get(j); - if (j != 0) { - out.print("\t\t"); - } - out.print(attribute.getValue()); - } - out.println(); - Thread.sleep(interval); - } - } - - public void ls(String line) throws Exception { - entries.clear(); - Map beans = proxy.getMBeans(null); - for (Map.Entry entry : beans.entrySet()) { - if ("com.alibaba.druid.pool.DruidDataSource".equals(entry.getValue().getClassName())) { - entries.add(new DataSourceEntry(entry.getKey(), entry.getValue())); - } - } - - for (int i = 0; i < entries.size(); ++i) { - out.println(i + " : " + entries.get(i).getObjectName()); - } - } - - public void desc(String line) throws Exception { - String arg = line.substring("desc ".length()); - int index = Integer.parseInt(arg); - DataSourceEntry current = entries.get(index); - - MBeanInfo mbeanInfo = current.getMbeanInfo(); - String[] attributes = new String[mbeanInfo.getAttributes().length]; - for (int i = 0; i < attributes.length; ++i) { - MBeanAttributeInfo attr = mbeanInfo.getAttributes()[i]; - attributes[i] = attr.getName(); - } - AttributeList values = proxy.getAttributes(current.getObjectName(), attributes); - for (int i = 0; i < attributes.length; ++i) { - out.println("\t" + attributes[i] + " : " + values.get(i)); - } - } - - public static void main(String[] args) throws Exception { - DruidConsole console = new DruidConsole(); - console.run(); - - } - - static class DataSourceEntry { - - private final ObjectName objectName; - private final MBeanInfo mbeanInfo; - - public DataSourceEntry(ObjectName objectName, MBeanInfo mbeanInfo){ - super(); - this.objectName = objectName; - this.mbeanInfo = mbeanInfo; - } - - public ObjectName getObjectName() { - return objectName; - } - - public MBeanInfo getMbeanInfo() { - return mbeanInfo; - } - - } -} diff --git a/src/main/java/com/alibaba/druid/pool/console/JConsoleContext.java b/src/main/java/com/alibaba/druid/pool/console/JConsoleContext.java deleted file mode 100644 index 6049bb4e07..0000000000 --- a/src/main/java/com/alibaba/druid/pool/console/JConsoleContext.java +++ /dev/null @@ -1,90 +0,0 @@ -package com.alibaba.druid.pool.console; - - -import java.beans.PropertyChangeListener; - -import javax.management.MBeanServerConnection; - -/** - * {@code JConsoleContext} represents a JConsole connection to a target - * application. - *

- * {@code JConsoleContext} notifies any {@code PropertyChangeListeners} - * about the {@linkplain #CONNECTION_STATE_PROPERTY ConnectionState} - * property change to {@link ConnectionState#CONNECTED CONNECTED} and - * {@link ConnectionState#DISCONNECTED DISCONNECTED}. - * The {@code JConsoleContext} instance will be the source for - * any generated events. - *

- * - * @since 1.6 - */ -public interface JConsoleContext { - /** - * The {@link ConnectionState ConnectionState} bound property name. - */ - public static String CONNECTION_STATE_PROPERTY = "connectionState"; - - /** - * Values for the {@linkplain #CONNECTION_STATE_PROPERTY - * ConnectionState} bound property. - */ - public enum ConnectionState { - /** - * The connection has been successfully established. - */ - CONNECTED, - /** - * No connection present. - */ - DISCONNECTED, - /** - * The connection is being attempted. - */ - CONNECTING - } - - /** - * Returns the {@link MBeanServerConnection MBeanServerConnection} for the - * connection to an application. The returned - * {@code MBeanServerConnection} object becomes invalid when - * the connection state is changed to the - * {@link ConnectionState#DISCONNECTED DISCONNECTED} state. - * - * @return the {@code MBeanServerConnection} for the - * connection to an application. - */ - public MBeanServerConnection getMBeanServerConnection(); - - /** - * Returns the current connection state. - * @return the current connection state. - */ - public ConnectionState getConnectionState(); - - /** - * Add a {@link java.beans.PropertyChangeListener PropertyChangeListener} - * to the listener list. - * The listener is registered for all properties. - * The same listener object may be added more than once, and will be called - * as many times as it is added. - * If {@code listener} is {@code null}, no exception is thrown and - * no action is taken. - * - * @param listener The {@code PropertyChangeListener} to be added - */ - public void addPropertyChangeListener(PropertyChangeListener listener); - - /** - * Removes a {@link java.beans.PropertyChangeListener PropertyChangeListener} - * from the listener list. This - * removes a {@code PropertyChangeListener} that was registered for all - * properties. If {@code listener} was added more than once to the same - * event source, it will be notified one less time after being removed. If - * {@code listener} is {@code null}, or was never added, no exception is - * thrown and no action is taken. - * - * @param listener the {@code PropertyChangeListener} to be removed - */ - public void removePropertyChangeListener(PropertyChangeListener listener); -} diff --git a/src/main/java/com/alibaba/druid/pool/console/LocalVirtualMachine.java b/src/main/java/com/alibaba/druid/pool/console/LocalVirtualMachine.java deleted file mode 100644 index bf22580367..0000000000 --- a/src/main/java/com/alibaba/druid/pool/console/LocalVirtualMachine.java +++ /dev/null @@ -1,252 +0,0 @@ -package com.alibaba.druid.pool.console; - -/* - * %W% %E% - * - * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved. - * ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. - */ - -import java.io.File; -import java.io.IOException; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Properties; -import java.util.Set; - -import sun.jvmstat.monitor.HostIdentifier; -import sun.jvmstat.monitor.MonitorException; -import sun.jvmstat.monitor.MonitoredHost; -import sun.jvmstat.monitor.MonitoredVm; -import sun.jvmstat.monitor.MonitoredVmUtil; -import sun.jvmstat.monitor.VmIdentifier; -import sun.management.ConnectorAddressLink; - -import com.sun.tools.attach.AgentInitializationException; -import com.sun.tools.attach.AgentLoadException; -import com.sun.tools.attach.AttachNotSupportedException; -import com.sun.tools.attach.VirtualMachine; -import com.sun.tools.attach.VirtualMachineDescriptor; - -@SuppressWarnings("restriction") -public class LocalVirtualMachine { - - private String address; - private String commandLine; - private String displayName; - private int vmid; - private boolean isAttachSupported; - - public LocalVirtualMachine(int vmid, String commandLine, boolean canAttach, String connectorAddress){ - this.vmid = vmid; - this.commandLine = commandLine; - this.address = connectorAddress; - this.isAttachSupported = canAttach; - this.displayName = getDisplayName(commandLine); - } - - private static String getDisplayName(String commandLine) { - // trim the pathname of jar file if it's a jar - String[] res = commandLine.split(" ", 2); - if (res[0].endsWith(".jar")) { - File jarfile = new File(res[0]); - String displayName = jarfile.getName(); - if (res.length == 2) { - displayName += " " + res[1]; - } - return displayName; - } - return commandLine; - } - - public int vmid() { - return vmid; - } - - public boolean isManageable() { - return (address != null); - } - - public boolean isAttachable() { - return isAttachSupported; - } - - public void startManagementAgent() throws IOException { - if (address != null) { - // already started - return; - } - - if (!isAttachable()) { - throw new IOException("This virtual machine \"" + vmid + "\" does not support dynamic attach."); - } - - loadManagementAgent(); - // fails to load or start the management agent - if (address == null) { - // should never reach here - throw new IOException("Fails to find connector address"); - } - } - - public String connectorAddress() { - // return null if not available or no JMX agent - return address; - } - - public String displayName() { - return displayName; - } - - public String toString() { - return commandLine; - } - - // This method returns the list of all virtual machines currently - // running on the machine - public static Map getAllVirtualMachines() { - Map map = new HashMap(); - getMonitoredVMs(map); - getAttachableVMs(map); - return map; - } - - private static void getMonitoredVMs(Map map) { - MonitoredHost host; - Set vms; - try { - host = MonitoredHost.getMonitoredHost(new HostIdentifier((String) null)); - vms = host.activeVms(); - } catch (java.net.URISyntaxException sx) { - throw new InternalError(sx.getMessage()); - } catch (MonitorException mx) { - throw new InternalError(mx.getMessage()); - } - for (Object vmid : vms) { - if (vmid instanceof Integer) { - int pid = ((Integer) vmid).intValue(); - String name = vmid.toString(); // default to pid if name not available - boolean attachable = false; - String address = null; - try { - MonitoredVm mvm = host.getMonitoredVm(new VmIdentifier(name)); - // use the command line as the display name - name = MonitoredVmUtil.commandLine(mvm); - attachable = MonitoredVmUtil.isAttachable(mvm); - address = ConnectorAddressLink.importFrom(pid); - mvm.detach(); - } catch (Exception x) { - // ignore - } - map.put((Integer) vmid, new LocalVirtualMachine(pid, name, attachable, address)); - } - } - } - - private static final String LOCAL_CONNECTOR_ADDRESS_PROP = "com.sun.management.jmxremote.localConnectorAddress"; - - private static void getAttachableVMs(Map map) { - List vms = VirtualMachine.list(); - for (VirtualMachineDescriptor vmd : vms) { - try { - Integer vmid = Integer.valueOf(vmd.id()); - if (!map.containsKey(vmid)) { - boolean attachable = false; - String address = null; - try { - VirtualMachine vm = VirtualMachine.attach(vmd); - attachable = true; - Properties agentProps = vm.getAgentProperties(); - address = (String) agentProps.get(LOCAL_CONNECTOR_ADDRESS_PROP); - vm.detach(); - } catch (AttachNotSupportedException x) { - // not attachable - } catch (IOException x) { - // ignore - } - map.put(vmid, new LocalVirtualMachine(vmid.intValue(), vmd.displayName(), attachable, address)); - } - } catch (NumberFormatException e) { - // do not support vmid different than pid - } - } - } - - public static LocalVirtualMachine getLocalVirtualMachine(int vmid) { - Map map = getAllVirtualMachines(); - LocalVirtualMachine lvm = map.get(vmid); - if (lvm == null) { - // Check if the VM is attachable but not included in the list - // if it's running with a different security context. - // For example, Windows services running - // local SYSTEM account are attachable if you have Adminstrator - // privileges. - boolean attachable = false; - String address = null; - String name = String.valueOf(vmid); // default display name to pid - try { - VirtualMachine vm = VirtualMachine.attach(name); - attachable = true; - Properties agentProps = vm.getAgentProperties(); - address = (String) agentProps.get(LOCAL_CONNECTOR_ADDRESS_PROP); - vm.detach(); - lvm = new LocalVirtualMachine(vmid, name, attachable, address); - } catch (AttachNotSupportedException x) { - // not attachable - x.printStackTrace(); - } catch (IOException x) { - // ignore - x.printStackTrace(); - } - } - return lvm; - } - - // load the management agent into the target VM - private void loadManagementAgent() throws IOException { - VirtualMachine vm = null; - String name = String.valueOf(vmid); - try { - vm = VirtualMachine.attach(name); - } catch (AttachNotSupportedException x) { - IOException ioe = new IOException(x.getMessage()); - ioe.initCause(x); - throw ioe; - } - - String home = vm.getSystemProperties().getProperty("java.home"); - - // Normally in ${java.home}/jre/lib/management-agent.jar but might - // be in ${java.home}/lib in build environments. - - String agent = home + File.separator + "jre" + File.separator + "lib" + File.separator + "management-agent.jar"; - File f = new File(agent); - if (!f.exists()) { - agent = home + File.separator + "lib" + File.separator + "management-agent.jar"; - f = new File(agent); - if (!f.exists()) { - throw new IOException("Management agent not found"); - } - } - - agent = f.getCanonicalPath(); - try { - vm.loadAgent(agent, "com.sun.management.jmxremote"); - } catch (AgentLoadException x) { - IOException ioe = new IOException(x.getMessage()); - ioe.initCause(x); - throw ioe; - } catch (AgentInitializationException x) { - IOException ioe = new IOException(x.getMessage()); - ioe.initCause(x); - throw ioe; - } - - // get the connector address - Properties agentProps = vm.getAgentProperties(); - address = (String) agentProps.get(LOCAL_CONNECTOR_ADDRESS_PROP); - - vm.detach(); - } -} diff --git a/src/main/java/com/alibaba/druid/pool/console/ProxyClient.java b/src/main/java/com/alibaba/druid/pool/console/ProxyClient.java deleted file mode 100644 index 53bafcdf07..0000000000 --- a/src/main/java/com/alibaba/druid/pool/console/ProxyClient.java +++ /dev/null @@ -1,993 +0,0 @@ -package com.alibaba.druid.pool.console; - -/* - * %W% %E% - * - * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved. - * ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. - */ - -import static java.lang.management.ManagementFactory.CLASS_LOADING_MXBEAN_NAME; -import static java.lang.management.ManagementFactory.COMPILATION_MXBEAN_NAME; -import static java.lang.management.ManagementFactory.GARBAGE_COLLECTOR_MXBEAN_DOMAIN_TYPE; -import static java.lang.management.ManagementFactory.MEMORY_MXBEAN_NAME; -import static java.lang.management.ManagementFactory.OPERATING_SYSTEM_MXBEAN_NAME; -import static java.lang.management.ManagementFactory.RUNTIME_MXBEAN_NAME; -import static java.lang.management.ManagementFactory.THREAD_MXBEAN_NAME; -import static java.lang.management.ManagementFactory.newPlatformMXBeanProxy; - -import java.beans.PropertyChangeEvent; -import java.beans.PropertyChangeListener; -import java.io.IOException; -import java.lang.management.ClassLoadingMXBean; -import java.lang.management.CompilationMXBean; -import java.lang.management.GarbageCollectorMXBean; -import java.lang.management.ManagementFactory; -import java.lang.management.MemoryMXBean; -import java.lang.management.OperatingSystemMXBean; -import java.lang.management.RuntimeMXBean; -import java.lang.management.ThreadMXBean; -import java.lang.ref.WeakReference; -import java.lang.reflect.InvocationHandler; -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; -import java.lang.reflect.Proxy; -import java.rmi.NotBoundException; -import java.rmi.Remote; -import java.rmi.registry.LocateRegistry; -import java.rmi.registry.Registry; -import java.rmi.server.RMIClientSocketFactory; -import java.rmi.server.RemoteObject; -import java.rmi.server.RemoteObjectInvocationHandler; -import java.rmi.server.RemoteRef; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collection; -import java.util.Collections; -import java.util.HashMap; -import java.util.Iterator; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.TreeSet; - -import javax.management.Attribute; -import javax.management.AttributeList; -import javax.management.AttributeNotFoundException; -import javax.management.InstanceNotFoundException; -import javax.management.IntrospectionException; -import javax.management.InvalidAttributeValueException; -import javax.management.MBeanException; -import javax.management.MBeanInfo; -import javax.management.MBeanOperationInfo; -import javax.management.MBeanServerConnection; -import javax.management.MalformedObjectNameException; -import javax.management.ObjectName; -import javax.management.ReflectionException; -import javax.management.remote.JMXConnector; -import javax.management.remote.JMXConnectorFactory; -import javax.management.remote.JMXServiceURL; -import javax.management.remote.rmi.RMIConnector; -import javax.management.remote.rmi.RMIServer; -import javax.rmi.ssl.SslRMIClientSocketFactory; -import javax.swing.event.SwingPropertyChangeSupport; - -import sun.rmi.server.UnicastRef2; -import sun.rmi.transport.LiveRef; - -import com.sun.management.HotSpotDiagnosticMXBean; - -@SuppressWarnings("restriction") -public class ProxyClient implements JConsoleContext { - - private ConnectionState connectionState = ConnectionState.DISCONNECTED; - - // The SwingPropertyChangeSupport will fire events on the EDT - private SwingPropertyChangeSupport propertyChangeSupport = new SwingPropertyChangeSupport( - this, - true); - - private static Map cache = Collections.synchronizedMap(new HashMap()); - - private volatile boolean isDead = true; - private String hostName = null; - private int port = 0; - private String userName = null; - private String password = null; - private boolean hasPlatformMXBeans = false; - private boolean hasHotSpotDiagnosticMXBean = false; - private boolean hasCompilationMXBean = false; - private boolean supportsLockUsage = false; - - // REVISIT: VMPanel and other places relying using getUrl(). - - // set only if it's created for local monitoring - private LocalVirtualMachine lvm; - - // set only if it's created from a given URL via the Advanced tab - private String advancedUrl = null; - - private JMXServiceURL jmxUrl = null; - private MBeanServerConnection mbsc = null; - private SnapshotMBeanServerConnection server = null; - private JMXConnector jmxc = null; - private RMIServer stub = null; - private static final SslRMIClientSocketFactory sslRMIClientSocketFactory = new SslRMIClientSocketFactory(); - private String registryHostName = null; - private int registryPort = 0; - private boolean vmConnector = false; - private boolean sslRegistry = false; - private boolean sslStub = false; - final private String connectionName; - final private String displayName; - - private ClassLoadingMXBean classLoadingMBean = null; - private CompilationMXBean compilationMBean = null; - private MemoryMXBean memoryMBean = null; - private OperatingSystemMXBean operatingSystemMBean = null; - private RuntimeMXBean runtimeMBean = null; - private ThreadMXBean threadMBean = null; - - private com.sun.management.OperatingSystemMXBean sunOperatingSystemMXBean = null; - private HotSpotDiagnosticMXBean hotspotDiagnosticMXBean = null; - - private List garbageCollectorMBeans = null; - - final static private String HOTSPOT_DIAGNOSTIC_MXBEAN_NAME = "com.sun.management:type=HotSpotDiagnostic"; - - private ProxyClient(String hostName, int port, String userName, String password) throws IOException{ - this.connectionName = getConnectionName(hostName, port, userName); - this.displayName = connectionName; - if (hostName.equals("localhost") && port == 0) { - // Monitor self - this.hostName = hostName; - this.port = port; - } else { - // Create an RMI connector client and connect it to - // the RMI connector server - final String urlPath = "/jndi/rmi://" + hostName + ":" + port + "/jmxrmi"; - JMXServiceURL url = new JMXServiceURL("rmi", "", 0, urlPath); - setParameters(url, userName, password); - vmConnector = true; - registryHostName = hostName; - registryPort = port; - checkSslConfig(); - } - } - - private ProxyClient(String url, String userName, String password) throws IOException{ - this.advancedUrl = url; - this.connectionName = getConnectionName(url, userName); - this.displayName = connectionName; - setParameters(new JMXServiceURL(url), userName, password); - } - - private ProxyClient(LocalVirtualMachine lvm) throws IOException{ - this.lvm = lvm; - this.connectionName = getConnectionName(lvm); - this.displayName = "pid: " + lvm.vmid() + " " + lvm.displayName(); - } - - private void setParameters(JMXServiceURL url, String userName, String password) { - this.jmxUrl = url; - this.hostName = jmxUrl.getHost(); - this.port = jmxUrl.getPort(); - this.userName = userName; - this.password = password; - } - - private static void checkStub(Remote stub, Class stubClass) { - // Check remote stub is from the expected class. - // - if (stub.getClass() != stubClass) { - if (!Proxy.isProxyClass(stub.getClass())) { - throw new SecurityException("Expecting a " + stubClass.getName() + " stub!"); - } else { - InvocationHandler handler = Proxy.getInvocationHandler(stub); - if (handler.getClass() != RemoteObjectInvocationHandler.class) { - throw new SecurityException("Expecting a dynamic proxy instance with a " - + RemoteObjectInvocationHandler.class.getName() - + " invocation handler!"); - } else { - stub = (Remote) handler; - } - } - } - // Check RemoteRef in stub is from the expected class - // "sun.rmi.server.UnicastRef2". - // - RemoteRef ref = ((RemoteObject) stub).getRef(); - if (ref.getClass() != UnicastRef2.class) { - throw new SecurityException("Expecting a " + UnicastRef2.class.getName() + " remote reference in stub!"); - } - // Check RMIClientSocketFactory in stub is from the expected class - // "javax.rmi.ssl.SslRMIClientSocketFactory". - // - LiveRef liveRef = ((UnicastRef2) ref).getLiveRef(); - RMIClientSocketFactory csf = liveRef.getClientSocketFactory(); - if (csf == null || csf.getClass() != SslRMIClientSocketFactory.class) { - throw new SecurityException("Expecting a " + SslRMIClientSocketFactory.class.getName() - + " RMI client socket factory in stub!"); - } - } - - private static final String rmiServerImplStubClassName = "javax.management.remote.rmi.RMIServerImpl_Stub"; - private static final Class rmiServerImplStubClass; - - static { - // FIXME: RMIServerImpl_Stub is generated at build time - // after jconsole is built. We need to investigate if - // the Makefile can be fixed to build jconsole in the - // right order. As a workaround for now, we dynamically - // load RMIServerImpl_Stub class instead of statically - // referencing it. - Class serverStubClass = null; - try { - serverStubClass = Class.forName(rmiServerImplStubClassName).asSubclass(Remote.class); - } catch (ClassNotFoundException e) { - // should never reach here - throw (InternalError) new InternalError(e.getMessage()).initCause(e); - } - rmiServerImplStubClass = serverStubClass; - } - - private void checkSslConfig() throws IOException { - // Get the reference to the RMI Registry and lookup RMIServer stub - // - Registry registry; - try { - registry = LocateRegistry.getRegistry(registryHostName, registryPort, sslRMIClientSocketFactory); - try { - stub = (RMIServer) registry.lookup("jmxrmi"); - } catch (NotBoundException nbe) { - throw (IOException) new IOException(nbe.getMessage()).initCause(nbe); - } - sslRegistry = true; - } catch (IOException e) { - registry = LocateRegistry.getRegistry(registryHostName, registryPort); - try { - stub = (RMIServer) registry.lookup("jmxrmi"); - } catch (NotBoundException nbe) { - throw (IOException) new IOException(nbe.getMessage()).initCause(nbe); - } - sslRegistry = false; - } - // Perform the checks for secure stub - // - try { - checkStub(stub, rmiServerImplStubClass); - sslStub = true; - } catch (SecurityException e) { - sslStub = false; - } - } - - /** - * Returns true if the underlying RMI registry is SSL-protected. - * - * @exception UnsupportedOperationException If this {@code ProxyClient} does not denote a JMX connector for a JMX VM - * agent. - */ - public boolean isSslRmiRegistry() { - // Check for VM connector - // - if (!isVmConnector()) { - throw new UnsupportedOperationException("ProxyClient.isSslRmiRegistry() is only supported if this " - + "ProxyClient is a JMX connector for a JMX VM agent"); - } - return sslRegistry; - } - - /** - * Returns true if the retrieved RMI stub is SSL-protected. - * - * @exception UnsupportedOperationException If this {@code ProxyClient} does not denote a JMX connector for a JMX VM - * agent. - */ - public boolean isSslRmiStub() { - // Check for VM connector - // - if (!isVmConnector()) { - throw new UnsupportedOperationException("ProxyClient.isSslRmiStub() is only supported if this " - + "ProxyClient is a JMX connector for a JMX VM agent"); - } - return sslStub; - } - - /** - * Returns true if this {@code ProxyClient} denotes a JMX connector for a JMX VM agent. - */ - public boolean isVmConnector() { - return vmConnector; - } - - private void setConnectionState(ConnectionState state) { - ConnectionState oldState = this.connectionState; - this.connectionState = state; - propertyChangeSupport.firePropertyChange(CONNECTION_STATE_PROPERTY, oldState, state); - } - - public ConnectionState getConnectionState() { - return this.connectionState; - } - - void flush() { - if (server != null) { - server.flush(); - } - } - - void connect() { - setConnectionState(ConnectionState.CONNECTING); - try { - tryConnect(); - setConnectionState(ConnectionState.CONNECTED); - } catch (Exception e) { - e.printStackTrace(); - setConnectionState(ConnectionState.DISCONNECTED); - } - } - - private void tryConnect() throws IOException { - if (jmxUrl == null && "localhost".equals(hostName) && port == 0) { - // Monitor self - this.jmxc = null; - this.mbsc = ManagementFactory.getPlatformMBeanServer(); - this.server = Snapshot.newSnapshot(mbsc); - } else { - // Monitor another process - if (lvm != null) { - if (!lvm.isManageable()) { - lvm.startManagementAgent(); - if (!lvm.isManageable()) { - // FIXME: what to throw - throw new IOException(lvm + "not manageable"); - } - } - if (this.jmxUrl == null) { - this.jmxUrl = new JMXServiceURL(lvm.connectorAddress()); - } - } - // Need to pass in credentials ? - if (userName == null && password == null) { - if (isVmConnector()) { - // Check for SSL config on reconnection only - if (stub == null) { - checkSslConfig(); - } - this.jmxc = new RMIConnector(stub, null); - jmxc.connect(); - } else { - this.jmxc = JMXConnectorFactory.connect(jmxUrl); - } - } else { - Map env = new HashMap(); - env.put(JMXConnector.CREDENTIALS, new String[] { userName, password }); - if (isVmConnector()) { - // Check for SSL config on reconnection only - if (stub == null) { - checkSslConfig(); - } - this.jmxc = new RMIConnector(stub, null); - jmxc.connect(env); - } else { - this.jmxc = JMXConnectorFactory.connect(jmxUrl, env); - } - } - this.mbsc = jmxc.getMBeanServerConnection(); - this.server = Snapshot.newSnapshot(mbsc); - } - this.isDead = false; - - try { - ObjectName on = new ObjectName(THREAD_MXBEAN_NAME); - this.hasPlatformMXBeans = server.isRegistered(on); - this.hasHotSpotDiagnosticMXBean = server.isRegistered(new ObjectName(HOTSPOT_DIAGNOSTIC_MXBEAN_NAME)); - // check if it has 6.0 new APIs - if (this.hasPlatformMXBeans) { - MBeanOperationInfo[] mopis = server.getMBeanInfo(on).getOperations(); - // look for findDeadlockedThreads operations; - for (MBeanOperationInfo op : mopis) { - if (op.getName().equals("findDeadlockedThreads")) { - this.supportsLockUsage = true; - break; - } - } - - on = new ObjectName(COMPILATION_MXBEAN_NAME); - this.hasCompilationMXBean = server.isRegistered(on); - } - } catch (MalformedObjectNameException e) { - // should not reach here - throw new InternalError(e.getMessage()); - } catch (IntrospectionException e) { - InternalError ie = new InternalError(e.getMessage()); - ie.initCause(e); - throw ie; - } catch (InstanceNotFoundException e) { - InternalError ie = new InternalError(e.getMessage()); - ie.initCause(e); - throw ie; - } catch (ReflectionException e) { - InternalError ie = new InternalError(e.getMessage()); - ie.initCause(e); - throw ie; - } - - if (hasPlatformMXBeans) { - // WORKAROUND for bug 5056632 - // Check if the access role is correct by getting a RuntimeMXBean - getRuntimeMXBean(); - } - } - - /** - * Gets a proxy client for a given local virtual machine. - */ - public static ProxyClient getProxyClient(LocalVirtualMachine lvm) throws IOException { - final String key = getCacheKey(lvm); - ProxyClient proxyClient = cache.get(key); - if (proxyClient == null) { - proxyClient = new ProxyClient(lvm); - cache.put(key, proxyClient); - } - return proxyClient; - } - - public static String getConnectionName(LocalVirtualMachine lvm) { - return Integer.toString(lvm.vmid()); - } - - private static String getCacheKey(LocalVirtualMachine lvm) { - return Integer.toString(lvm.vmid()); - } - - /** - * Gets a proxy client for a given JMXServiceURL. - */ - public static ProxyClient getProxyClient(String url, String userName, String password) throws IOException { - final String key = getCacheKey(url, userName, password); - ProxyClient proxyClient = cache.get(key); - if (proxyClient == null) { - proxyClient = new ProxyClient(url, userName, password); - cache.put(key, proxyClient); - } - return proxyClient; - } - - public static String getConnectionName(String url, String userName) { - if (userName != null && userName.length() > 0) { - return userName + "@" + url; - } else { - return url; - } - } - - private static String getCacheKey(String url, String userName, String password) { - return (url == null ? "" : url) + ":" + (userName == null ? "" : userName) + ":" - + (password == null ? "" : password); - } - - /** - * Gets a proxy client for a given "hostname:port". - */ - public static ProxyClient getProxyClient(String hostName, int port, String userName, String password) - throws IOException { - final String key = getCacheKey(hostName, port, userName, password); - ProxyClient proxyClient = cache.get(key); - if (proxyClient == null) { - proxyClient = new ProxyClient(hostName, port, userName, password); - cache.put(key, proxyClient); - } - return proxyClient; - } - - public static String getConnectionName(String hostName, int port, String userName) { - String name = hostName + ":" + port; - if (userName != null && userName.length() > 0) { - return userName + "@" + name; - } else { - return name; - } - } - - private static String getCacheKey(String hostName, int port, String userName, String password) { - return (hostName == null ? "" : hostName) + ":" + port + ":" + (userName == null ? "" : userName) + ":" - + (password == null ? "" : password); - } - - public String connectionName() { - return connectionName; - } - - public String getDisplayName() { - return displayName; - } - - public String toString() { - if (!isConnected()) { - return displayName + " (disconnected)"; - } else { - return displayName; - } - } - - public MBeanServerConnection getMBeanServerConnection() { - return mbsc; - } - - public SnapshotMBeanServerConnection getSnapshotMBeanServerConnection() { - return server; - } - - public String getUrl() { - return advancedUrl; - } - - public String getHostName() { - return hostName; - } - - public int getPort() { - return port; - } - - public int getVmid() { - return (lvm != null) ? lvm.vmid() : 0; - } - - public String getUserName() { - return userName; - } - - public String getPassword() { - return password; - } - - public void disconnect() { - // Reset remote stub - stub = null; - // Close MBeanServer connection - if (jmxc != null) { - try { - jmxc.close(); - } catch (IOException e) { - // Ignore ??? - } - } - // Reset platform MBean references - classLoadingMBean = null; - compilationMBean = null; - memoryMBean = null; - operatingSystemMBean = null; - runtimeMBean = null; - threadMBean = null; - sunOperatingSystemMXBean = null; - garbageCollectorMBeans = null; - // Set connection state to DISCONNECTED - if (!isDead) { - isDead = true; - setConnectionState(ConnectionState.DISCONNECTED); - } - } - - /** - * Returns the list of domains in which any MBean is currently registered. - */ - public String[] getDomains() throws IOException { - return server.getDomains(); - } - - /** - * Returns a map of MBeans with ObjectName as the key and MBeanInfo value of a given domain. If domain is - * null, all MBeans are returned. If no MBean found, an empty map is returned. - */ - public Map getMBeans(String domain) throws IOException { - - ObjectName name = null; - if (domain != null) { - try { - name = new ObjectName(domain + ":*"); - } catch (MalformedObjectNameException e) { - // should not reach here - assert (false); - } - } - Set mbeans = server.queryNames(name, null); - Map result = new HashMap(mbeans.size()); - Iterator iterator = mbeans.iterator(); - while (iterator.hasNext()) { - Object object = iterator.next(); - if (object instanceof ObjectName) { - ObjectName o = (ObjectName) object; - try { - MBeanInfo info = server.getMBeanInfo(o); - result.put(o, info); - } catch (IntrospectionException e) { - // TODO: should log the error - } catch (InstanceNotFoundException e) { - // TODO: should log the error - } catch (ReflectionException e) { - // TODO: should log the error - } - } - } - return result; - } - - /** - * Returns a list of attributes of a named MBean. - */ - public AttributeList getAttributes(ObjectName name, String[] attributes) throws IOException { - AttributeList list = null; - try { - list = server.getAttributes(name, attributes); - } catch (InstanceNotFoundException e) { - // TODO: A MBean may have been unregistered. - // need to set up listener to listen for MBeanServerNotification. - } catch (ReflectionException e) { - // TODO: should log the error - } - return list; - } - - /** - * Set the value of a specific attribute of a named MBean. - */ - public void setAttribute(ObjectName name, Attribute attribute) throws InvalidAttributeValueException, - MBeanException, IOException { - try { - server.setAttribute(name, attribute); - } catch (InstanceNotFoundException e) { - // TODO: A MBean may have been unregistered. - } catch (AttributeNotFoundException e) { - assert (false); - } catch (ReflectionException e) { - // TODO: should log the error - } - } - - /** - * Invokes an operation of a named MBean. - * - * @throws MBeanException Wraps an exception thrown by the MBean's invoked method. - */ - public Object invoke(ObjectName name, String operationName, Object[] params, String[] signature) - throws IOException, - MBeanException { - Object result = null; - try { - result = server.invoke(name, operationName, params, signature); - } catch (InstanceNotFoundException e) { - // TODO: A MBean may have been unregistered. - } catch (ReflectionException e) { - // TODO: should log the error - } - return result; - } - - public synchronized ClassLoadingMXBean getClassLoadingMXBean() throws IOException { - if (hasPlatformMXBeans && classLoadingMBean == null) { - classLoadingMBean = newPlatformMXBeanProxy(server, CLASS_LOADING_MXBEAN_NAME, ClassLoadingMXBean.class); - } - return classLoadingMBean; - } - - public synchronized CompilationMXBean getCompilationMXBean() throws IOException { - if (hasCompilationMXBean && compilationMBean == null) { - compilationMBean = newPlatformMXBeanProxy(server, COMPILATION_MXBEAN_NAME, CompilationMXBean.class); - } - return compilationMBean; - } - - public synchronized Collection getGarbageCollectorMXBeans() throws IOException { - - // TODO: How to deal with changes to the list?? - if (garbageCollectorMBeans == null) { - ObjectName gcName = null; - try { - gcName = new ObjectName(GARBAGE_COLLECTOR_MXBEAN_DOMAIN_TYPE + ",*"); - } catch (MalformedObjectNameException e) { - // should not reach here - assert (false); - } - Set mbeans = server.queryNames(gcName, null); - if (mbeans != null) { - garbageCollectorMBeans = new ArrayList(); - Iterator iterator = mbeans.iterator(); - while (iterator.hasNext()) { - ObjectName on = (ObjectName) iterator.next(); - String name = GARBAGE_COLLECTOR_MXBEAN_DOMAIN_TYPE + ",name=" + on.getKeyProperty("name"); - - GarbageCollectorMXBean mBean = newPlatformMXBeanProxy(server, name, GarbageCollectorMXBean.class); - garbageCollectorMBeans.add(mBean); - } - } - } - return garbageCollectorMBeans; - } - - public synchronized MemoryMXBean getMemoryMXBean() throws IOException { - if (hasPlatformMXBeans && memoryMBean == null) { - memoryMBean = newPlatformMXBeanProxy(server, MEMORY_MXBEAN_NAME, MemoryMXBean.class); - } - return memoryMBean; - } - - public synchronized RuntimeMXBean getRuntimeMXBean() throws IOException { - if (hasPlatformMXBeans && runtimeMBean == null) { - runtimeMBean = newPlatformMXBeanProxy(server, RUNTIME_MXBEAN_NAME, RuntimeMXBean.class); - } - return runtimeMBean; - } - - public synchronized ThreadMXBean getThreadMXBean() throws IOException { - if (hasPlatformMXBeans && threadMBean == null) { - threadMBean = newPlatformMXBeanProxy(server, THREAD_MXBEAN_NAME, ThreadMXBean.class); - } - return threadMBean; - } - - public synchronized OperatingSystemMXBean getOperatingSystemMXBean() throws IOException { - if (hasPlatformMXBeans && operatingSystemMBean == null) { - operatingSystemMBean = newPlatformMXBeanProxy(server, OPERATING_SYSTEM_MXBEAN_NAME, - OperatingSystemMXBean.class); - } - return operatingSystemMBean; - } - - public synchronized com.sun.management.OperatingSystemMXBean getSunOperatingSystemMXBean() throws IOException { - - try { - ObjectName on = new ObjectName(OPERATING_SYSTEM_MXBEAN_NAME); - if (sunOperatingSystemMXBean == null) { - if (server.isInstanceOf(on, "com.sun.management.OperatingSystemMXBean")) { - sunOperatingSystemMXBean = newPlatformMXBeanProxy(server, OPERATING_SYSTEM_MXBEAN_NAME, - com.sun.management.OperatingSystemMXBean.class); - } - } - } catch (InstanceNotFoundException e) { - return null; - } catch (MalformedObjectNameException e) { - return null; // should never reach here - } - return sunOperatingSystemMXBean; - } - - public synchronized HotSpotDiagnosticMXBean getHotSpotDiagnosticMXBean() throws IOException { - if (hasHotSpotDiagnosticMXBean && hotspotDiagnosticMXBean == null) { - hotspotDiagnosticMXBean = newPlatformMXBeanProxy(server, HOTSPOT_DIAGNOSTIC_MXBEAN_NAME, - HotSpotDiagnosticMXBean.class); - } - return hotspotDiagnosticMXBean; - } - - public T getMXBean(ObjectName objName, Class interfaceClass) throws IOException { - return newPlatformMXBeanProxy(server, objName.toString(), interfaceClass); - - } - - // Return thread IDs of deadlocked threads or null if any. - // It finds deadlocks involving only monitors if it's a Tiger VM. - // Otherwise, it finds deadlocks involving both monitors and - // the concurrent locks. - public long[] findDeadlockedThreads() throws IOException { - ThreadMXBean tm = getThreadMXBean(); - if (supportsLockUsage && tm.isSynchronizerUsageSupported()) { - return tm.findDeadlockedThreads(); - } else { - return tm.findMonitorDeadlockedThreads(); - } - } - - public synchronized void markAsDead() { - disconnect(); - } - - public boolean isDead() { - return isDead; - } - - boolean isConnected() { - return !isDead(); - } - - boolean hasPlatformMXBeans() { - return this.hasPlatformMXBeans; - } - - boolean hasHotSpotDiagnosticMXBean() { - return this.hasHotSpotDiagnosticMXBean; - } - - boolean isLockUsageSupported() { - return supportsLockUsage; - } - - public boolean isRegistered(ObjectName name) throws IOException { - return server.isRegistered(name); - } - - public void addPropertyChangeListener(PropertyChangeListener listener) { - propertyChangeSupport.addPropertyChangeListener(listener); - } - - public void addWeakPropertyChangeListener(PropertyChangeListener listener) { - if (!(listener instanceof WeakPCL)) { - listener = new WeakPCL(listener); - } - propertyChangeSupport.addPropertyChangeListener(listener); - } - - public void removePropertyChangeListener(PropertyChangeListener listener) { - if (!(listener instanceof WeakPCL)) { - // Search for the WeakPCL holding this listener (if any) - for (PropertyChangeListener pcl : propertyChangeSupport.getPropertyChangeListeners()) { - if (pcl instanceof WeakPCL && ((WeakPCL) pcl).get() == listener) { - listener = pcl; - break; - } - } - } - propertyChangeSupport.removePropertyChangeListener(listener); - } - - /** - * The PropertyChangeListener is handled via a WeakReference so as not to pin down the listener. - */ - private class WeakPCL extends WeakReference implements PropertyChangeListener { - - WeakPCL(PropertyChangeListener referent){ - super(referent); - } - - public void propertyChange(PropertyChangeEvent pce) { - PropertyChangeListener pcl = get(); - - if (pcl == null) { - // The referent listener was GC'ed, we're no longer - // interested in PropertyChanges, remove the listener. - dispose(); - } else { - pcl.propertyChange(pce); - } - } - - private void dispose() { - removePropertyChangeListener(this); - } - } - - // - // Snapshot MBeanServerConnection: - // - // This is an object that wraps an existing MBeanServerConnection and adds - // caching to it, as follows: - // - // - The first time an attribute is called in a given MBean, the result is - // cached. Every subsequent time getAttribute is called for that attribute - // the cached result is returned. - // - // - Before every call to VMPanel.update() or when the Refresh button in the - // Attributes table is pressed down the attributes cache is flushed. Then - // any subsequent call to getAttribute will retrieve all the values for - // the attributes that are known to the cache. - // - // - The attributes cache uses a learning approach and only the attributes - // that are in the cache will be retrieved between two subsequent updates. - // - - public interface SnapshotMBeanServerConnection extends MBeanServerConnection { - - /** - * Flush all cached values of attributes. - */ - public void flush(); - } - - public static class Snapshot { - - private Snapshot(){ - } - - public static SnapshotMBeanServerConnection newSnapshot(MBeanServerConnection mbsc) { - final InvocationHandler ih = new SnapshotInvocationHandler(mbsc); - return (SnapshotMBeanServerConnection) Proxy.newProxyInstance(Snapshot.class.getClassLoader(), - new Class[] { SnapshotMBeanServerConnection.class }, - ih); - } - } - - static class SnapshotInvocationHandler implements InvocationHandler { - - private final MBeanServerConnection conn; - private Map cachedValues = newMap(); - private Map> cachedNames = newMap(); - - @SuppressWarnings("serial") - private static final class NameValueMap extends HashMap { - } - - SnapshotInvocationHandler(MBeanServerConnection conn){ - this.conn = conn; - } - - synchronized void flush() { - cachedValues = newMap(); - } - - public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { - final String methodName = method.getName(); - if (methodName.equals("getAttribute")) { - return getAttribute((ObjectName) args[0], (String) args[1]); - } else if (methodName.equals("getAttributes")) { - return getAttributes((ObjectName) args[0], (String[]) args[1]); - } else if (methodName.equals("flush")) { - flush(); - return null; - } else { - try { - return method.invoke(conn, args); - } catch (InvocationTargetException e) { - throw e.getCause(); - } - } - } - - private Object getAttribute(ObjectName objName, String attrName) throws MBeanException, - InstanceNotFoundException, - AttributeNotFoundException, - ReflectionException, IOException { - final NameValueMap values = getCachedAttributes(objName, Collections.singleton(attrName)); - Object value = values.get(attrName); - if (value != null || values.containsKey(attrName)) { - return value; - } - // Not in cache, presumably because it was omitted from the - // getAttributes result because of an exception. Following - // call will probably provoke the same exception. - return conn.getAttribute(objName, attrName); - } - - private AttributeList getAttributes(ObjectName objName, String[] attrNames) throws InstanceNotFoundException, - ReflectionException, IOException { - final NameValueMap values = getCachedAttributes(objName, new TreeSet(Arrays.asList(attrNames))); - final AttributeList list = new AttributeList(); - for (String attrName : attrNames) { - final Object value = values.get(attrName); - if (value != null || values.containsKey(attrName)) { - list.add(new Attribute(attrName, value)); - } - } - return list; - } - - private synchronized NameValueMap getCachedAttributes(ObjectName objName, Set attrNames) - throws InstanceNotFoundException, - ReflectionException, - IOException { - NameValueMap values = cachedValues.get(objName); - if (values != null && values.keySet().containsAll(attrNames)) { - return values; - } - attrNames = new TreeSet(attrNames); - Set oldNames = cachedNames.get(objName); - if (oldNames != null) { - attrNames.addAll(oldNames); - } - values = new NameValueMap(); - final AttributeList attrs = conn.getAttributes(objName, attrNames.toArray(new String[attrNames.size()])); - for (Attribute attr : attrs.asList()) { - values.put(attr.getName(), attr.getValue()); - } - cachedValues.put(objName, values); - cachedNames.put(objName, attrNames); - return values; - } - - // See http://www.artima.com/weblogs/viewpost.jsp?thread=79394 - private static Map newMap() { - return new HashMap(); - } - } -} diff --git a/src/main/java/com/alibaba/druid/sql/parser/Lexer.java b/src/main/java/com/alibaba/druid/sql/parser/Lexer.java index 897e3c1605..99ec0915d0 100644 --- a/src/main/java/com/alibaba/druid/sql/parser/Lexer.java +++ b/src/main/java/com/alibaba/druid/sql/parser/Lexer.java @@ -503,9 +503,11 @@ public class Lexer { token = LITERAL_CHARS; break; } else { - System.arraycopy(buf, np + 1, sbuf, 0, sp); - hasSpecial = true; - putChar('\''); + if (!hasSpecial) { + System.arraycopy(buf, np + 1, sbuf, 0, sp); + hasSpecial = true; + } + putChar('\''); continue; } } diff --git a/src/main/java/com/alibaba/druid/sql/visitor/ParameterizedOutputVisitorUtils.java b/src/main/java/com/alibaba/druid/sql/visitor/ParameterizedOutputVisitorUtils.java index c5cb5c1f99..a7b52adafc 100644 --- a/src/main/java/com/alibaba/druid/sql/visitor/ParameterizedOutputVisitorUtils.java +++ b/src/main/java/com/alibaba/druid/sql/visitor/ParameterizedOutputVisitorUtils.java @@ -34,18 +34,18 @@ public class ParameterizedOutputVisitorUtils { public static SQLASTOutputVisitor createParameterizedOutputVisitor(Appendable out, String dbType) { if (JdbcUtils.ORACLE.equals(dbType)) { - return new OracleParameterizedOutputVisitor(); + return new OracleParameterizedOutputVisitor(out); } if (JdbcUtils.MYSQL.equals(dbType)) { - return new MySqlParameterizedOutputVisitor(); + return new MySqlParameterizedOutputVisitor(out); } if (JdbcUtils.POSTGRESQL.equals(dbType)) { - return new PGParameterizedOutputVisitor(); + return new PGParameterizedOutputVisitor(out); } - return new ParameterizedOutputVisitor(); + return new ParameterizedOutputVisitor(out); } public static boolean visit(SQLASTOutputVisitor v, SQLInListExpr x) { diff --git a/src/main/java/com/alibaba/druid/stat/JdbcDataSourceStat.java b/src/main/java/com/alibaba/druid/stat/JdbcDataSourceStat.java index d87e8acba2..10b7394bf6 100644 --- a/src/main/java/com/alibaba/druid/stat/JdbcDataSourceStat.java +++ b/src/main/java/com/alibaba/druid/stat/JdbcDataSourceStat.java @@ -16,6 +16,7 @@ package com.alibaba.druid.stat; import java.util.HashMap; +import java.util.Iterator; import java.util.LinkedHashMap; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; @@ -41,7 +42,7 @@ public class JdbcDataSourceStat implements JdbcDataSourceStatMBean { private final JdbcResultSetStat resultSetStat = new JdbcResultSetStat(); private final JdbcStatementStat statementStat = new JdbcStatementStat(); - private int maxSize = 1000 * 10; + private int maxSize = 1000 * 1; private ReentrantReadWriteLock lock = new ReentrantReadWriteLock(); private final LinkedHashMap sqlStatMap = new LinkedHashMap( @@ -62,14 +63,21 @@ public class JdbcDataSourceStat implements JdbcDataSourceStatMBean { connectionStat.reset(); statementStat.reset(); resultSetStat.reset(); - - lock.readLock().lock(); + + lock.writeLock().lock(); try { - for (JdbcSqlStat stat : sqlStatMap.values()) { - stat.reset(); - } + Iterator> iter = sqlStatMap.entrySet().iterator(); + while (iter.hasNext()) { + Map.Entry entry = iter.next(); + JdbcSqlStat stat = entry.getValue(); + if (stat.getExecuteCount() == 0) { + iter.remove(); + } else { + stat.reset(); + } + } } finally { - lock.readLock().unlock(); + lock.writeLock().unlock(); } for (JdbcConnectionStat.Entry connectionStat : connections.values()) { diff --git a/src/main/resources/META-INF/druid-filter.properties b/src/main/resources/META-INF/druid-filter.properties index b7967b127c..675e0fdcc1 100644 --- a/src/main/resources/META-INF/druid-filter.properties +++ b/src/main/resources/META-INF/druid-filter.properties @@ -1,5 +1,6 @@ druid.filters.default=com.alibaba.druid.filter.stat.StatFilter druid.filters.stat=com.alibaba.druid.filter.stat.StatFilter +druid.filters.mergeStat=com.alibaba.druid.filter.stat.MergeStatFilter druid.filters.counter=com.alibaba.druid.filter.stat.StatFilter druid.filters.encoding=com.alibaba.druid.filter.encoding.EncodingConvertFilter druid.filters.log4j=com.alibaba.druid.filter.logging.Log4jFilter diff --git a/src/test/java/com/alibaba/druid/bvt/sql/oracle/OracleSelectTest34.java b/src/test/java/com/alibaba/druid/bvt/sql/oracle/OracleSelectTest34.java index eacf38362a..7f87d876f1 100644 --- a/src/test/java/com/alibaba/druid/bvt/sql/oracle/OracleSelectTest34.java +++ b/src/test/java/com/alibaba/druid/bvt/sql/oracle/OracleSelectTest34.java @@ -38,6 +38,7 @@ public class OracleSelectTest34 extends OracleTest { OracleSchemaStatVisitor visitor = new OracleSchemaStatVisitor(); statemen.accept(visitor); + System.out.println("Tables : " + visitor.getTables()); System.out.println("fields : " + visitor.getColumns()); diff --git a/src/test/java/com/alibaba/druid/sql/OracleTest.java b/src/test/java/com/alibaba/druid/sql/OracleTest.java index 35edd6da50..ba110b3b0f 100644 --- a/src/test/java/com/alibaba/druid/sql/OracleTest.java +++ b/src/test/java/com/alibaba/druid/sql/OracleTest.java @@ -27,4 +27,6 @@ public class OracleTest extends TestCase { } System.out.println(text); } + + } diff --git a/src/test/java/com/alibaba/druid/sql/parser/SQLLexerTest2.java b/src/test/java/com/alibaba/druid/sql/parser/SQLLexerTest2.java index 1e778c62be..a08ef644f1 100644 --- a/src/test/java/com/alibaba/druid/sql/parser/SQLLexerTest2.java +++ b/src/test/java/com/alibaba/druid/sql/parser/SQLLexerTest2.java @@ -24,4 +24,29 @@ public class SQLLexerTest2 extends TestCase { } } } + + public void test_lexer2() throws Exception { + String sql = "SELECT substr('''a''bc',0,3) FROM dual"; + Lexer lexer = new Lexer(sql); + for (;;) { + lexer.nextToken(); + Token tok = lexer.token(); + + if (tok == Token.IDENTIFIER) { + System.out.println(tok.name() + "\t\t" + lexer.stringVal()); + } else if (tok == Token.LITERAL_INT) { + System.out.println(tok.name() + "\t\t" + lexer.numberString()); + } else if (tok == Token.LITERAL_CHARS) { + System.out.println(tok.name() + "\t\t" + lexer.stringVal()); + } + else { + System.out.println(tok.name() + "\t\t\t" + tok.name); + } + + if (tok == Token.EOF) { + break; + } + } + } + }