--- /dev/null
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2013 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * SonarQube is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+package org.sonar.core.persistence.profiling;
+
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+
+class InvocationUtils {
+
+ private InvocationUtils() {
+ // Only private stuff
+ }
+
+ static Object invokeQuietly(Object target, Method method, Object[] params) throws Throwable {
+ Object result = null;
+ try {
+ result = method.invoke(target, params);
+ } catch(InvocationTargetException invocationException) {
+ for (Class<?> exceptionClass: method.getExceptionTypes()) {
+ if (exceptionClass.isInstance(invocationException.getCause())) {
+ throw invocationException.getCause();
+ }
+ throw new IllegalStateException(invocationException.getCause());
+ }
+ }
+ return result;
+ }
+}
@Override
public Object invoke(Object target, Method method, Object[] args) throws Throwable {
- Object result = method.invoke(connection, args);
+ Object result = InvocationUtils.invokeQuietly(connection, method, args);
if ("prepareStatement".equals(method.getName())) {
PreparedStatement statement = (PreparedStatement) result;
String sql = (String) args[0];
*/
package org.sonar.core.persistence.profiling;
-import org.apache.commons.lang.StringUtils;
import com.google.common.collect.Lists;
+import org.apache.commons.lang.StringUtils;
import org.sonar.core.profiling.StopWatch;
import java.lang.reflect.InvocationHandler;
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
if (method.getName().startsWith("execute")) {
StopWatch watch = PROFILING.start();
- Object result = method.invoke(statement, args);
- StringBuilder sqlBuilder = new StringBuilder().append(sql);
- if (!arguments.isEmpty()) {
- sqlBuilder.append(" - parameters are: ");
- for (Object arg: arguments) {
- sqlBuilder.append(PARAM_PREFIX).append(arg).append(PARAM_SUFFIX).append(PARAM_SEPARATOR);
+ Object result = null;
+ try {
+ result = InvocationUtils.invokeQuietly(statement, method, args);
+ } finally {
+ StringBuilder sqlBuilder = new StringBuilder().append(sql);
+ if (!arguments.isEmpty()) {
+ sqlBuilder.append(" - parameters are: ");
+ for (Object arg: arguments) {
+ sqlBuilder.append(PARAM_PREFIX).append(arg).append(PARAM_SUFFIX).append(PARAM_SEPARATOR);
+ }
}
+ PROFILING.stop(watch, StringUtils.removeEnd(sqlBuilder.toString(), PARAM_SEPARATOR));
}
- PROFILING.stop(watch, StringUtils.removeEnd(sqlBuilder.toString(), PARAM_SEPARATOR));
return result;
} else if (method.getName().startsWith("set") && args.length > 1) {
arguments.set((Integer) args[0] - 1, args[1]);
- return method.invoke(statement, args);
+ return InvocationUtils.invokeQuietly(statement, method, args);
} else {
- return method.invoke(statement, args);
+ return InvocationUtils.invokeQuietly(statement, method, args);
}
}
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
if (method.getName().startsWith("execute")) {
StopWatch watch = PROFILING.start();
- Object result = method.invoke(statement, args);
- PROFILING.stop(watch, (String) args[0]);
+ Object result = null;
+ try {
+ result = InvocationUtils.invokeQuietly(statement, method, args);
+ } finally {
+ PROFILING.stop(watch, (String) args[0]);
+ }
return result;
} else {
- return method.invoke(statement, args);
+ return InvocationUtils.invokeQuietly(statement, method, args);
}
}
}
--- /dev/null
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2013 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * SonarQube is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+package org.sonar.core.persistence.profiling;
+
+import org.fest.assertions.Fail;
+import org.junit.Test;
+
+import java.sql.Connection;
+import java.sql.SQLException;
+
+import static org.fest.assertions.Assertions.assertThat;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+public class InvocationUtilsTest {
+
+ @Test
+ public void should_return_result() throws Throwable {
+ String toString = "toString";
+ Object target = mock(Object.class);
+ when(target.toString()).thenReturn(toString);
+
+ assertThat(InvocationUtils.invokeQuietly(target, Object.class.getMethod("toString"), new Object[0])).isEqualTo(toString);
+ }
+
+ @Test
+ public void should_throw_declared_exception() throws Throwable {
+ Connection target = mock(Connection.class);
+ String failSql = "any sql";
+ when(target.prepareStatement(failSql)).thenThrow(new SQLException("Expected"));
+
+ try {
+ InvocationUtils.invokeQuietly(target, Connection.class.getMethod("prepareStatement", String.class), new Object[] { failSql });
+ Fail.fail();
+ } catch (Throwable t) {
+ assertThat(t).isInstanceOf(SQLException.class);
+ }
+ }
+
+ @Test
+ public void should_wrap_undeclared_exception() throws Throwable {
+ Connection target = mock(Connection.class);
+ String failSql = "any sql";
+ when(target.prepareStatement(failSql)).thenThrow(new SQLException("Expected"));
+
+ try {
+ InvocationUtils.invokeQuietly(target, Object.class.getMethod("wait"), new Object[0]);
+ Fail.fail();
+ } catch (Throwable t) {
+ assertThat(t).isInstanceOf(IllegalStateException.class);
+ }
+ }
+}
import org.sonar.core.profiling.Profiling;
import java.io.ByteArrayInputStream;
-import java.sql.Connection;
-import java.sql.Date;
-import java.sql.PreparedStatement;
-import java.sql.Statement;
-import java.sql.Timestamp;
+import java.sql.*;
import static org.fest.assertions.Assertions.assertThat;
import static org.mockito.Mockito.mock;