| /* |
| * Licensed to the Apache Software Foundation (ASF) under one or more |
| * contributor license agreements. See the NOTICE file distributed with |
| * this work for additional information regarding copyright ownership. |
| * The ASF licenses this file to You under the Apache License, Version 2.0 |
| * (the "License"); you may not use this file except in compliance with |
| * the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| package org.apache.tomcat.jdbc.test; |
| |
| import java.util.Map; |
| |
| import org.junit.Assert; |
| import org.junit.Test; |
| |
| import org.apache.tomcat.jdbc.pool.PoolProperties; |
| import org.apache.tomcat.jdbc.pool.PoolProperties.InterceptorDefinition; |
| import org.apache.tomcat.jdbc.pool.PoolProperties.InterceptorProperty; |
| import org.apache.tomcat.jdbc.pool.TrapException; |
| |
| /** |
| * Test of JdbcInterceptor configuration parsing in the |
| * {@link org.apache.tomcat.jdbc.pool.PoolProperties PoolProperties} class. |
| * Added in context of bug 54395. |
| */ |
| public class TestJdbcInterceptorConfigParsing { |
| |
| @Test |
| public void testBasic() throws Exception { |
| String interceptorConfig = "FirstInterceptor;SecondInterceptor(parm1=value1,parm2=value2)"; |
| PoolProperties props = new PoolProperties(); |
| props.setJdbcInterceptors(interceptorConfig); |
| InterceptorDefinition[] interceptorDefs = props.getJdbcInterceptorsAsArray(); |
| Assert.assertNotNull(interceptorDefs); |
| |
| // 3 items because parser automatically inserts TrapException interceptor to front of list |
| Assert.assertEquals(interceptorDefs.length, 3); |
| Assert.assertEquals(interceptorDefs[0].getClassName(), TrapException.class.getName()); |
| |
| Assert.assertNotNull(interceptorDefs[1]); |
| Assert.assertEquals(interceptorDefs[1].getClassName(), "FirstInterceptor"); |
| Assert.assertNotNull(interceptorDefs[2]); |
| Assert.assertEquals(interceptorDefs[2].getClassName(), "SecondInterceptor"); |
| |
| Map<String, InterceptorProperty> secondProps = interceptorDefs[2].getProperties(); |
| Assert.assertNotNull(secondProps); |
| Assert.assertEquals(secondProps.size(), 2); |
| Assert.assertNotNull(secondProps.get("parm1")); |
| Assert.assertEquals(secondProps.get("parm1").getValue(), "value1"); |
| Assert.assertNotNull(secondProps.get("parm2")); |
| Assert.assertEquals(secondProps.get("parm2").getValue(), "value2"); |
| } |
| |
| @Test |
| public void testWhitespace() throws Exception { |
| String interceptorConfig = "FirstInterceptor ; \n" + |
| "SecondInterceptor (parm1 = value1 , parm2= value2 ) ; \n\n" + |
| "\t org.cyb.ThirdInterceptor(parm1=value1); \n" + |
| "EmptyParmValInterceptor(parm1= )"; |
| PoolProperties props = new PoolProperties(); |
| props.setJdbcInterceptors(interceptorConfig); |
| InterceptorDefinition[] interceptorDefs = props.getJdbcInterceptorsAsArray(); |
| Assert.assertNotNull(interceptorDefs); |
| |
| // 5 items because parser automatically inserts TrapException interceptor to front of list |
| Assert.assertEquals(interceptorDefs.length, 5); |
| Assert.assertEquals(interceptorDefs[0].getClassName(), TrapException.class.getName()); |
| |
| Assert.assertNotNull(interceptorDefs[1]); |
| Assert.assertEquals(interceptorDefs[1].getClassName(), "FirstInterceptor"); |
| Assert.assertNotNull(interceptorDefs[2]); |
| Assert.assertEquals(interceptorDefs[2].getClassName(), "SecondInterceptor"); |
| Assert.assertNotNull(interceptorDefs[3]); |
| Assert.assertEquals(interceptorDefs[3].getClassName(), "org.cyb.ThirdInterceptor"); |
| |
| Map<String, InterceptorProperty> secondProps = interceptorDefs[2].getProperties(); |
| Assert.assertNotNull(secondProps); |
| Assert.assertEquals(secondProps.size(), 2); |
| Assert.assertNotNull(secondProps.get("parm1")); |
| Assert.assertEquals(secondProps.get("parm1").getValue(), "value1"); |
| Assert.assertNotNull(secondProps.get("parm2")); |
| Assert.assertEquals(secondProps.get("parm2").getValue(), "value2"); // Bug 54395 |
| |
| Map<String, InterceptorProperty> thirdProps = interceptorDefs[3].getProperties(); |
| Assert.assertNotNull(thirdProps); |
| Assert.assertEquals(thirdProps.size(), 1); |
| Assert.assertNotNull(thirdProps.get("parm1")); |
| Assert.assertEquals(thirdProps.get("parm1").getValue(), "value1"); |
| |
| Map<String, InterceptorProperty> emptyParmValProps = interceptorDefs[4].getProperties(); |
| Assert.assertNotNull(emptyParmValProps); |
| Assert.assertEquals(emptyParmValProps.size(), 1); |
| Assert.assertNotNull(emptyParmValProps.get("parm1")); |
| Assert.assertEquals(emptyParmValProps.get("parm1").getValue(), ""); |
| } |
| |
| /** |
| * Some of these should probably be handled more cleanly by the parser, but a few known |
| * exception scenarios are presented here just to document current behavior. In many cases |
| * failure in parsing will just be propagated to a definition that will fail later |
| * when instantiated. Should we be failing faster (and with more detail)? |
| * |
| * @throws Exception |
| */ |
| @Test |
| public void testExceptionOrNot() throws Exception { |
| PoolProperties props = null; |
| |
| String[] exceptionInducingConfigs = { |
| "EmptyParmsInterceptor()", |
| "WhitespaceParmsInterceptor( )" |
| }; |
| for (String badConfig : exceptionInducingConfigs) { |
| props = new PoolProperties(); |
| props.setJdbcInterceptors(badConfig); |
| try { |
| props.getJdbcInterceptorsAsArray(); |
| Assert.fail("Expected exception."); |
| } catch (Exception e) { |
| // Expected |
| } |
| } |
| |
| String[] noExceptionButInvalidConfigs = { |
| "MalformedParmsInterceptor(= )", |
| "MalformedParmsInterceptor( =)", |
| "MalformedParmsInterceptor(", |
| "MalformedParmsInterceptor( ", |
| "MalformedParmsInterceptor)", |
| "MalformedParmsInterceptor) ", |
| "MalformedParmsInterceptor )" |
| }; |
| for (String badConfig : noExceptionButInvalidConfigs) { |
| props = new PoolProperties(); |
| props.setJdbcInterceptors(badConfig); |
| try { |
| props.getJdbcInterceptorsAsArray(); |
| } catch (Exception e) { |
| Assert.fail("Unexpected exception."); |
| } |
| } |
| } |
| |
| @Test |
| public void textExtraSemicolonBehavior() { |
| |
| // This one DOES get an extra/empty definition |
| PoolProperties props = new PoolProperties(); |
| props.setJdbcInterceptors(";EmptyLeadingSemiInterceptor"); |
| InterceptorDefinition[] jiDefs = props.getJdbcInterceptorsAsArray(); |
| Assert.assertNotNull(jiDefs); |
| Assert.assertEquals(jiDefs.length, 3); |
| |
| // This one does NOT get an extra/empty definition (no trailing whitespace) |
| props = new PoolProperties(); |
| props.setJdbcInterceptors("EmptyTrailingSemiInterceptor;"); |
| jiDefs = props.getJdbcInterceptorsAsArray(); |
| Assert.assertNotNull(jiDefs); |
| Assert.assertEquals(jiDefs.length, 2); |
| |
| // This one DOES get an extra/empty definition (with trailing whitespace) |
| props = new PoolProperties(); |
| props.setJdbcInterceptors("EmptyTrailingSemiInterceptor; "); |
| jiDefs = props.getJdbcInterceptorsAsArray(); |
| Assert.assertNotNull(jiDefs); |
| Assert.assertEquals(jiDefs.length, 3); |
| } |
| } |