diff --git a/custom-checks/checkstyle/src/main/java/org/openhab/tools/analysis/checkstyle/ExceptionLastParameterCheck.java b/custom-checks/checkstyle/src/main/java/org/openhab/tools/analysis/checkstyle/ExceptionLastParameterCheck.java new file mode 100644 index 00000000..e8876dd6 --- /dev/null +++ b/custom-checks/checkstyle/src/main/java/org/openhab/tools/analysis/checkstyle/ExceptionLastParameterCheck.java @@ -0,0 +1,273 @@ +/** + * Copyright (c) 2010-2018 by the respective copyright holders. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + */ +package org.openhab.tools.analysis.checkstyle; + +import java.text.MessageFormat; +import java.util.LinkedList; +import java.util.Queue; +import java.util.stream.Collectors; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import com.puppycrawl.tools.checkstyle.api.AbstractCheck; +import com.puppycrawl.tools.checkstyle.api.DetailAST; +import com.puppycrawl.tools.checkstyle.api.TokenTypes; +import com.puppycrawl.tools.checkstyle.utils.CheckUtils; +import com.puppycrawl.tools.checkstyle.utils.CommonUtils; + +/** + * Checks the code and generates a warning if an exception is caught and logged + * and it is not set as a last parameter to the logging. + * + * @author Tanya Georgieva - Initial Contribution + */ +public class ExceptionLastParameterCheck extends AbstractCheck { + + private static final Class EXCEPTION = Exception.class; + private static final Class RUNTIME_EXCEPTION = RuntimeException.class; + + private static final String EXCEPTION_AS_LAST_PARAMETER_MSG = "Please set exception as last parameter"; + private static final String FULL_STACK_TRACE_MSG = "Log exception full stack trace"; + private static final String FULL_STACK_TRACE_EXCEPTION_AS_LAST_PARAMETER_MSG = EXCEPTION_AS_LAST_PARAMETER_MSG + .concat(" and ").concat(FULL_STACK_TRACE_MSG); + + private static final String EXCEPTION_PACKAGE = "java.lang."; + private static final String LOG_LEVEL_ERROR = "error"; + private static final String LOGGER = "logger"; + + private final Log logger = LogFactory.getLog(ExceptionLastParameterCheck.class); + + private LinkedList imports = new LinkedList<>(); + private LinkedList exceptions = new LinkedList<>(); + + private String exceptionName = ""; + + @Override + public int[] getDefaultTokens() { + return getAcceptableTokens(); + } + + @Override + public int[] getAcceptableTokens() { + return new int[] { TokenTypes.LITERAL_CATCH, TokenTypes.IMPORT }; + } + + @Override + public int[] getRequiredTokens() { + return CommonUtils.EMPTY_INT_ARRAY; + } + + @Override + public void visitToken(DetailAST ast) { + // imports are always prior to catch blocks + if (ast.getType() == TokenTypes.IMPORT) { + String currentImport = CheckUtils.createFullType(ast).getText(); + this.imports.add(currentImport); + } else { + findLoggedExceptions(ast); + } + } + + private void findLoggedExceptions(DetailAST catchAst) { + extractCaughtExceptions(catchAst); + + LinkedList loggers = getAllChildrenNodesOfType(catchAst.getLastChild(), TokenTypes.EXPR); + if (loggers.isEmpty()) { + LinkedList requiredNodes = new LinkedList<>(); + // if the logger is in if-else-statement the list of loggers would be empty. + // the logger nodes we are looking for are nested, so we use recursion to find them + loggers = getAllNodesOfType(requiredNodes, catchAst.getLastChild(), TokenTypes.EXPR); + } + for (DetailAST loggerNode : loggers) { + DetailAST currentLogger = getLogger(loggerNode); + if (currentLogger != null) { + String logLevel = currentLogger.getNextSibling().getText(); + Class currentExceptionClass = getExceptionClass(); + boolean isExceptionUnchecked = RUNTIME_EXCEPTION.isAssignableFrom(currentExceptionClass); + boolean isExceptionChecked = !isExceptionUnchecked && EXCEPTION.isAssignableFrom(currentExceptionClass); + boolean isExceptionValid = isExceptionUnchecked + || (isExceptionChecked && LOG_LEVEL_ERROR.equals(logLevel)); + if (isExceptionValid) { + // ELIST node contains the logger's parameters + DetailAST elistAst = loggerNode.getFirstChild().findFirstToken(TokenTypes.ELIST); + LinkedList parameters = getAllChildrenNodesOfType(elistAst, TokenTypes.EXPR); + validateLogger(parameters); + } + } + } + } + + private void validateLogger(LinkedList parameters) { + int lastParameterPosition = parameters.size(); + int logLineNumber = 0; + // checking if exception parameter is with full stack trace + boolean isFullStackTraceExceptionFound = false; + // checking if at some position in the logger + // there is exception parameter calling one of its methods + boolean isExceptionCallingMethodFound = false; + int fullStackTraceExceptionPosition = 0; + int exceptionCallingMethodPosition = 0; + + for (int i = 0; i < lastParameterPosition; i++) { + DetailAST currentParameter = getFirstNode(parameters.get(i).getFirstChild(), TokenTypes.IDENT); + // The current parameter would be null if it's token type is anything different than IDENT. + // For example the parameter could be of type STRING_LITERAL or NUM_INT. + // In this case: logger.trace("\"{}\" is not a valid integer number.", e, value) + // the current parameters will be "value" and "e" + if (currentParameter != null) { + String currentParameterName = currentParameter.getText(); + logLineNumber = currentParameter.getLineNo(); + + if (this.exceptionName.equals(currentParameterName)) { + // if a parameter is calling a method - e.getMessage() + // the abstract syntax tree will represent the method call as its sibling + // so we are checking the childCount of the parameter's parent + boolean isParameterCallingMethod = currentParameter.getParent().getChildCount() > 1; + int parameterPosition = i + 1; + + if (!isParameterCallingMethod) { + isFullStackTraceExceptionFound = true; + fullStackTraceExceptionPosition = parameterPosition; + } else { + isExceptionCallingMethodFound = true; + exceptionCallingMethodPosition = parameterPosition; + } + } + } + } + // Log message when the exception parameter is not set as last: + // logger.trace("StringExample", e, e.getMessage()); + if (isFullStackTraceExceptionFound && fullStackTraceExceptionPosition != lastParameterPosition) { + log(logLineNumber, EXCEPTION_AS_LAST_PARAMETER_MSG); + } + + if (!isFullStackTraceExceptionFound && isExceptionCallingMethodFound) { + if (exceptionCallingMethodPosition == lastParameterPosition) { + // Log message when the exception parameter is not logged with the full stack trace: + // logger.trace("StringExample", e.getMessage()); + log(logLineNumber, FULL_STACK_TRACE_MSG); + } else { + // Log message when the exception parameter is not logged with the full stack trace + // and is not set as last: logger.trace("StringExample", e.getMessage(), value); + log(logLineNumber, FULL_STACK_TRACE_EXCEPTION_AS_LAST_PARAMETER_MSG); + } + } + } + + private Class getExceptionClass() { + for (DetailAST exceptionNode : this.exceptions) { + String exception = exceptionNode.getText(); + // get the package and the class name for the exception: + // "java.lang.annotation.AnnotationTypeMismatchException" + String fullyQualifiedExceptionName = this.imports.stream().filter(e -> e.endsWith("." + exception)) + .collect(Collectors.joining()); + // if the fullyQualifiedExceptionName is empty + // the caught exception is from package "java.lang" which is not imported + if (fullyQualifiedExceptionName.isEmpty()) { + fullyQualifiedExceptionName = EXCEPTION_PACKAGE + exception; + } + + try { + Class exceptionClass = Class.forName(fullyQualifiedExceptionName); + return exceptionClass; + } catch (ClassNotFoundException e) { + String message = MessageFormat.format("Exception class {0} not found.", fullyQualifiedExceptionName); + logger.info(message, e); + } + } + return null; + } + + private void extractCaughtExceptions(DetailAST catchAst) { + DetailAST catchBlockParameters = catchAst.findFirstToken(TokenTypes.PARAMETER_DEF); + DetailAST parametersType = catchBlockParameters.findFirstToken(TokenTypes.TYPE); + DetailAST currentException = parametersType.getFirstChild(); + + this.exceptionName = catchBlockParameters.getLastChild().getText(); + // if there are more than one caught exceptions: + // catch (ArithmeticException | NumberFormatException e) + // the current exception node will be the binary or operator "|" + if (currentException.getType() != TokenTypes.IDENT) { + this.exceptions = getAllChildrenNodesOfType(currentException, TokenTypes.IDENT); + } else { + this.exceptions = getAllChildrenNodesOfType(parametersType, TokenTypes.IDENT); + } + } + + private DetailAST getLogger(DetailAST ast) { + if (ast == null) { + return null; + } + if (LOGGER.equalsIgnoreCase(ast.getText())) { + return ast; + } + return getLogger(ast.getFirstChild()); + } + + /** + * Find the first (direct or indirect) child node of a given type + * + * @param DetailAST {@link DetailAST} instance + * @param type the token type to match + */ + private DetailAST getFirstNode(DetailAST ast, int type) { + if (ast == null) { + return null; + } + if (ast.getType() == type) { + return ast; + } + DetailAST nextNode = getFirstNode(ast.getFirstChild(), type); + DetailAST nextSibling = getFirstNode(ast.getNextSibling(), type); + // if the current node does not have a child node return its sibling + return nextNode != null ? nextNode : nextSibling; + } + + /** + * Collect all direct children nodes of a given type + * + * @param DetailAST {@link DetailAST} instance + * @param type the token type to match + */ + private LinkedList getAllChildrenNodesOfType(DetailAST ast, int type) { + LinkedList children = new LinkedList<>(); + Queue visitedNodes = new LinkedList<>(); + visitedNodes.add(ast.getFirstChild()); + + while (!visitedNodes.isEmpty()) { + DetailAST currentNode = visitedNodes.poll(); + if (currentNode.getType() == type) { + children.add(currentNode); + } + if (currentNode.getNextSibling() != null) { + visitedNodes.add(currentNode.getNextSibling()); + } + } + return children; + } + + /** + * Collect all direct and indirect children nodes of a given type using recursion + * + * @param DetailAST {@link DetailAST} instance + * @param type the token type to match + */ + private LinkedList getAllNodesOfType(LinkedList requiredNodes, DetailAST ast, int type) { + if (ast == null) { + return new LinkedList<>(); + } + if (ast.getType() == type) { + requiredNodes.add(ast); + } + getAllNodesOfType(requiredNodes, ast.getFirstChild(), type); + getAllNodesOfType(requiredNodes, ast.getNextSibling(), type); + return requiredNodes; + } +} diff --git a/custom-checks/checkstyle/src/test/java/org/openhab/tools/analysis/checkstyle/test/ExceptionLastParameterCheckTest.java b/custom-checks/checkstyle/src/test/java/org/openhab/tools/analysis/checkstyle/test/ExceptionLastParameterCheckTest.java new file mode 100644 index 00000000..2ca94b05 --- /dev/null +++ b/custom-checks/checkstyle/src/test/java/org/openhab/tools/analysis/checkstyle/test/ExceptionLastParameterCheckTest.java @@ -0,0 +1,178 @@ +/** + * Copyright (c) 2010-2018 by the respective copyright holders. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + */ +package org.openhab.tools.analysis.checkstyle.test; + +import java.io.File; + +import org.junit.Test; +import org.openhab.tools.analysis.checkstyle.ExceptionLastParameterCheck; +import org.openhab.tools.analysis.checkstyle.api.AbstractStaticCheckTest; + +import com.puppycrawl.tools.checkstyle.DefaultConfiguration; +import com.puppycrawl.tools.checkstyle.utils.CommonUtils; + +/** + * Tests for {@link ExceptionLastParameterCheck} + * + * @author Tanya Georgieva - Initial Contribution + */ +public class ExceptionLastParameterCheckTest extends AbstractStaticCheckTest { + + private static final String TEST_DIRECTORY_NAME = "exceptionLastParameterCheckTest"; + + private static final String EXCEPTION_AS_LAST_PARAMETER_MSG = "Please set exception as last parameter"; + private static final String FULL_STACK_TRACE_MSG = "Log exception full stack trace"; + private static final String FULL_STACK_TRACE_EXCEPTION_AS_LAST_PARAMETER_MSG = EXCEPTION_AS_LAST_PARAMETER_MSG + .concat(" and ").concat(FULL_STACK_TRACE_MSG); + + private static DefaultConfiguration config = createCheckConfig(ExceptionLastParameterCheck.class); + + @Test + public void verifCaughtCheckedExceptionWithInvalidParameter() throws Exception { + verifyJavaFile("CaughtCheckedExceptionWithInvalidParameter.java", + generateExpectedMessages(14, FULL_STACK_TRACE_MSG, 27, FULL_STACK_TRACE_MSG)); + } + + @Test + public void verifCaughtCheckedExceptionWithInvalidLogLevel() throws Exception { + verifyJavaFile("CaughtCheckedExceptionWithInvalidLogLevel.java", CommonUtils.EMPTY_STRING_ARRAY); + } + + @Test + public void verifCaughtCheckedExceptionWithValidLogLevel() throws Exception { + verifyJavaFile("CaughtCheckedExceptionWithValidLogLevel.java", generateExpectedMessages(14, + EXCEPTION_AS_LAST_PARAMETER_MSG, 27, FULL_STACK_TRACE_EXCEPTION_AS_LAST_PARAMETER_MSG)); + } + + @Test + public void verifCaughtUncheckedExceptionWithValidLogger() throws Exception { + verifyJavaFile("CaughtUncheckedExceptionWithValidLogger.java", CommonUtils.EMPTY_STRING_ARRAY); + } + + @Test + public void verifCaughtUncheckedExceptionWithInvalidLogger() throws Exception { + verifyJavaFile("CaughtUncheckedExceptionWithInvalidLogger.java", + generateExpectedMessages(9, FULL_STACK_TRACE_MSG)); + } + + @Test + public void verifyValidIndirectExceptionOfRuntimeException() throws Exception { + verifyJavaFile("ValidIndirectExceptionOfRuntimeException.java", CommonUtils.EMPTY_STRING_ARRAY); + } + + @Test + public void verifyCaughtUncheckedExceptionForMultipleLoggers() throws Exception { + verifyJavaFile("CaughtUncheckedExceptionForMultipleLoggers.java", CommonUtils.EMPTY_STRING_ARRAY); + } + + @Test + public void verifyClassWithoutCatchBlock() throws Exception { + verifyJavaFile("ClassWithoutCatchBlock.java", CommonUtils.EMPTY_STRING_ARRAY); + } + + @Test + public void verifyInvalidLoggedUncheckedException() throws Exception { + verifyJavaFile("InvalidLoggedUncheckedException.java", + generateExpectedMessages(14, FULL_STACK_TRACE_MSG, 16, FULL_STACK_TRACE_MSG)); + } + + @Test + public void verifyValidLoggerMultipleParameters() throws Exception { + verifyJavaFile("ValidLoggerMultipleParameters.java", generateExpectedMessages(16, FULL_STACK_TRACE_MSG)); + } + + @Test + public void verifyInvalidLoggerWithMultipleExceptions() throws Exception { + verifyJavaFile("InvalidLoggerWithMultipleExceptions.java", generateExpectedMessages(26, FULL_STACK_TRACE_MSG, + 30, FULL_STACK_TRACE_MSG, 34, FULL_STACK_TRACE_MSG, 38, FULL_STACK_TRACE_MSG)); + } + + @Test + public void verifyLoggerInIfElseStatement() throws Exception { + verifyJavaFile("LoggerInIfElseStatement.java", generateExpectedMessages(18, EXCEPTION_AS_LAST_PARAMETER_MSG, 25, + FULL_STACK_TRACE_EXCEPTION_AS_LAST_PARAMETER_MSG)); + } + + @Test + public void verifyInvalidIndirectExceptionOfRuntimeException() throws Exception { + verifyJavaFile("InvalidIndirectExceptionOfRuntimeException.java", + generateExpectedMessages(12, EXCEPTION_AS_LAST_PARAMETER_MSG)); + } + + @Test + public void verifyInvalidLoggerMultipleParameters() throws Exception { + verifyJavaFile("InvalidLoggerMultipleParameters.java", + generateExpectedMessages(20, EXCEPTION_AS_LAST_PARAMETER_MSG)); + } + + @Test + public void verifyCaughtUncheckedExceptionWithMethodCall() throws Exception { + verifyJavaFile("CaughtUncheckedExceptionWithMethodCall.java", + generateExpectedMessages(34, FULL_STACK_TRACE_MSG)); + } + + @Test + public void verifyValidMultipleExceptions() throws Exception { + verifyJavaFile("ValidMultipleExceptions.java", CommonUtils.EMPTY_STRING_ARRAY); + } + + @Test + public void verifyMultipleCatchBlocksWithInvalidLogger() throws Exception { + verifyJavaFile("MultipleCatchBlocksWithInvalidLogger.java", + generateExpectedMessages(12, FULL_STACK_TRACE_EXCEPTION_AS_LAST_PARAMETER_MSG)); + } + + @Test + public void verifyInvalidLoggerWithMultipleExceptionParameters() throws Exception { + verifyJavaFile("InvalidLoggerWithMultipleExceptionParameters.java", + generateExpectedMessages(27, EXCEPTION_AS_LAST_PARAMETER_MSG)); + } + + @Test + public void verifyValidLoggerWihtMultipleCatch() throws Exception { + verifyJavaFile("ValidLoggerWihtMultipleCatch.java", CommonUtils.EMPTY_STRING_ARRAY); + } + + @Test + public void verifyInvalidLogger() throws Exception { + verifyJavaFile("InvalidLogger.java", generateExpectedMessages(13, EXCEPTION_AS_LAST_PARAMETER_MSG)); + } + + @Test + public void verifyInvalidLoggerUpperCase() throws Exception { + verifyJavaFile("InvalidLoggerUpperCase.java", generateExpectedMessages(24, FULL_STACK_TRACE_MSG)); + } + + @Test + public void verifyExceptionsWithLogger() throws Exception { + verifyJavaFile("ExceptionsWithLogger.java", + generateExpectedMessages(12, FULL_STACK_TRACE_MSG, 14, FULL_STACK_TRACE_MSG, 24, FULL_STACK_TRACE_MSG)); + } + + @Test + public void verifyCheckedExceptionWithInvalidLogger() throws Exception { + verifyJavaFile("CheckedExceptionWithInvalidLogger.java", + generateExpectedMessages(40, EXCEPTION_AS_LAST_PARAMETER_MSG)); + } + + @Test + public void verifyLoggerWithMultipleParametersWithoutException() throws Exception { + verifyJavaFile("LoggerWithMultipleParametersWithoutException.java", CommonUtils.EMPTY_STRING_ARRAY); + } + + @Test + public void verifCaughtAndLoggedError() throws Exception { + verifyJavaFile("CaughtAndLoggedError.java", CommonUtils.EMPTY_STRING_ARRAY); + } + + private void verifyJavaFile(String fileName, String[] expected) throws Exception { + String absolutePath = getPath(TEST_DIRECTORY_NAME + File.separator + fileName); + verify(config, absolutePath, expected); + } +} diff --git a/custom-checks/checkstyle/src/test/resources/checkstyle/exceptionLastParameterCheckTest/CaughtAndLoggedError.java b/custom-checks/checkstyle/src/test/resources/checkstyle/exceptionLastParameterCheckTest/CaughtAndLoggedError.java new file mode 100644 index 00000000..dd5ce221 --- /dev/null +++ b/custom-checks/checkstyle/src/test/resources/checkstyle/exceptionLastParameterCheckTest/CaughtAndLoggedError.java @@ -0,0 +1,32 @@ +import java.util.concurrent.TimeUnit; + +import org.eclipse.smarthome.core.thing.ThingStatus; + +public class CaughtAndLoggedError { + + @Override + public void initialize() { + logger.debug("Initializing handler for Pioneer AVR @{}", connection.getConnectionName()); + updateStatus(ThingStatus.ONLINE); + + // Start the status checker + Runnable statusChecker = new Runnable() { + @Override + public void run() { + try { + logger.debug("Checking status of AVR @{}", connection.getConnectionName()); + checkStatus(); + } catch (LinkageError e) { + logger.warn( + "Failed to check the status for AVR @{}. If a Serial link is used to connect to the AVR, please check that the Bundle org.openhab.io.transport.serial is available. Cause: {}", + connection.getConnectionName(), e, e.getMessage()); + // Stop to check the status of this AVR. + if (statusCheckerFuture != null) { + statusCheckerFuture.cancel(false); + } + } + } + }; + statusCheckerFuture = scheduler.scheduleWithFixedDelay(statusChecker, 1, 10, TimeUnit.SECONDS); + } +} diff --git a/custom-checks/checkstyle/src/test/resources/checkstyle/exceptionLastParameterCheckTest/CaughtCheckedExceptionWithInvalidLogLevel.java b/custom-checks/checkstyle/src/test/resources/checkstyle/exceptionLastParameterCheckTest/CaughtCheckedExceptionWithInvalidLogLevel.java new file mode 100644 index 00000000..31e2c78d --- /dev/null +++ b/custom-checks/checkstyle/src/test/resources/checkstyle/exceptionLastParameterCheckTest/CaughtCheckedExceptionWithInvalidLogLevel.java @@ -0,0 +1,30 @@ +import java.lang.reflect.InvocationTargetException; +import java.rmi.activation.ActivationException; +import java.security.acl.AclNotFoundException; + +public class CaughtCheckedExceptionWithInvalidLogLevel { + + private CULHandlerInternal createNewHandler(T config) throws CULDeviceException { + try { + // empty for the purpose of the test + } catch (SecurityException e1) { + logger.error(" ... ", e1); + // checked exception + } catch (ActivationException e1) { + logger.info(" ... ", e1.getMessage()); + } catch (IllegalArgumentException e) { + logger.error(" ... ", e); + // checked exception + } catch (InstantiationException e) { + logger.error(" ... ", e); + } catch (IllegalAccessException e) { + logger.error(" ... ", e); + // checked exception + } catch (InvocationTargetException e) { + logger.error(" ... ", e); + // checked exception + } catch (AclNotFoundException e) { + logger.debug(" ... ", e.getMethod()); + } + } +} diff --git a/custom-checks/checkstyle/src/test/resources/checkstyle/exceptionLastParameterCheckTest/CaughtCheckedExceptionWithInvalidParameter.java b/custom-checks/checkstyle/src/test/resources/checkstyle/exceptionLastParameterCheckTest/CaughtCheckedExceptionWithInvalidParameter.java new file mode 100644 index 00000000..030411b2 --- /dev/null +++ b/custom-checks/checkstyle/src/test/resources/checkstyle/exceptionLastParameterCheckTest/CaughtCheckedExceptionWithInvalidParameter.java @@ -0,0 +1,30 @@ +import java.lang.reflect.InvocationTargetException; +import java.rmi.activation.ActivationException; +import java.security.acl.AclNotFoundException; + +public class CaughtCheckedExceptionWithInvalidParameter { + + private CULHandlerInternal createNewHandler(T config) throws CULDeviceException { + try { + // empty for the purpose of the test + } catch (SecurityException e1) { + logger.error(" ... ", e1); + // checked exception + } catch (ActivationException e1) { + logger.error(" ... ", e1.getMessage()); + } catch (IllegalArgumentException e) { + logger.error(" ... ", e); + // checked exception + } catch (InstantiationException e) { + logger.error(" ... ", e); + } catch (IllegalAccessException e) { + logger.error(" ... ", e); + // checked exception + } catch (InvocationTargetException e) { + logger.error(" ... ", e); + // checked exception + } catch (AclNotFoundException e) { + logger.error(" ... ", e.getMethod()); + } + } +} diff --git a/custom-checks/checkstyle/src/test/resources/checkstyle/exceptionLastParameterCheckTest/CaughtCheckedExceptionWithValidLogLevel.java b/custom-checks/checkstyle/src/test/resources/checkstyle/exceptionLastParameterCheckTest/CaughtCheckedExceptionWithValidLogLevel.java new file mode 100644 index 00000000..bd712f34 --- /dev/null +++ b/custom-checks/checkstyle/src/test/resources/checkstyle/exceptionLastParameterCheckTest/CaughtCheckedExceptionWithValidLogLevel.java @@ -0,0 +1,30 @@ +import java.lang.reflect.InvocationTargetException; +import java.rmi.activation.ActivationException; +import java.security.acl.AclNotFoundException; + +public class CaughtCheckedExceptionWithValidLogLevel { + + private CULHandlerInternal createNewHandler(T config) throws CULDeviceException { + try { + // empty for the purpose of the test + } catch (SecurityException e1) { + logger.error(" ... ", e1); + // checked exception + } catch (ActivationException e1) { + logger.error(" ... ", e1, e1.getMessage()); + } catch (IllegalArgumentException e) { + logger.error(" ... ", e); + // checked exception + } catch (InstantiationException e) { + logger.error(" ... ", e); + } catch (IllegalAccessException e) { + logger.error(" ... ", e); + // checked exception + } catch (InvocationTargetException e) { + logger.error(" ... ", e); + // checked exception + } catch (AclNotFoundException e) { + logger.error(e.getMethod(), " ... "); + } + } +} diff --git a/custom-checks/checkstyle/src/test/resources/checkstyle/exceptionLastParameterCheckTest/CaughtUncheckedExceptionForMultipleLoggers.java b/custom-checks/checkstyle/src/test/resources/checkstyle/exceptionLastParameterCheckTest/CaughtUncheckedExceptionForMultipleLoggers.java new file mode 100644 index 00000000..5745f6d7 --- /dev/null +++ b/custom-checks/checkstyle/src/test/resources/checkstyle/exceptionLastParameterCheckTest/CaughtUncheckedExceptionForMultipleLoggers.java @@ -0,0 +1,20 @@ +import static org.eclipse.smarthome.binding.hue.HueBindingConstants.USER_NAME; + +import org.eclipse.smarthome.config.core.Configuration; + +public class CaughtUncheckedExceptionForMultipleLoggers { + + private void updateBridgeThingConfiguration(String userName) { + Configuration config = editConfiguration(); + config.put(USER_NAME, userName); + + try { + updateConfiguration(config); + logger.debug("Updated configuration parameter {} to '{}'", USER_NAME, userName); + } catch (IllegalStateException e) { + logger.trace("Configuration update failed.", e); + logger.warn("Unable to update configuration of Hue bridge."); + logger.warn("Please configure the following user name manually: {}", userName); + } + } +} diff --git a/custom-checks/checkstyle/src/test/resources/checkstyle/exceptionLastParameterCheckTest/CaughtUncheckedExceptionWithInvalidLogger.java b/custom-checks/checkstyle/src/test/resources/checkstyle/exceptionLastParameterCheckTest/CaughtUncheckedExceptionWithInvalidLogger.java new file mode 100644 index 00000000..59675c6d --- /dev/null +++ b/custom-checks/checkstyle/src/test/resources/checkstyle/exceptionLastParameterCheckTest/CaughtUncheckedExceptionWithInvalidLogger.java @@ -0,0 +1,15 @@ +public class CaughtUncheckedExceptionWithInvalidLogger { + + private CULHandlerInternal createNewHandler(T config) throws CULDeviceException { + try { + // empty for the purpose of the test + } catch (SecurityException e1) { + logger.error(" ... ", e1); + } catch (IllegalArgumentException e) { + logger.error(" ... ", e.getMessage()); + //checked exception + } catch (IllegalAccessException e) { + logger.error(" ... ", e); + } + } +} diff --git a/custom-checks/checkstyle/src/test/resources/checkstyle/exceptionLastParameterCheckTest/CaughtUncheckedExceptionWithMethodCall.java b/custom-checks/checkstyle/src/test/resources/checkstyle/exceptionLastParameterCheckTest/CaughtUncheckedExceptionWithMethodCall.java new file mode 100644 index 00000000..e1ee6f90 --- /dev/null +++ b/custom-checks/checkstyle/src/test/resources/checkstyle/exceptionLastParameterCheckTest/CaughtUncheckedExceptionWithMethodCall.java @@ -0,0 +1,39 @@ +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.security.GeneralSecurityException; + +import javax.crypto.Cipher; +import javax.crypto.spec.IvParameterSpec; + +import org.openhab.binding.zwave.internal.protocol.SecurityEncapsulatedSerialMessage; +import org.openhab.binding.zwave.internal.protocol.SerialMessage; +import org.openhab.binding.zwave.internal.protocol.SerialMessage.SerialMessageClass; +import org.openhab.binding.zwave.internal.protocol.SerialMessage.SerialMessageType; +import org.openhab.binding.zwave.internal.protocol.commandclass.ZWaveCommandClass; +import org.openhab.binding.zwave.internal.protocol.commandclass.ZWaveDoorLockCommandClass; +import org.openhab.binding.zwave.internal.protocol.commandclass.ZWaveSecurityPayloadFrame; +import org.openhab.binding.zwave.internal.protocol.commandclass.ZWaveSecureNonceTracker.Nonce; + +public class CaughtUncheckedExceptionWithMethodCall { + + protected void sendNextMessageUsingDeviceNonce() { + if (payloadEncapsulationQueue.isEmpty()) { + logger.warn("NODE {}: payloadQueue was empty, returning", this.getNode().getNodeId()); + return; + } + + ZWaveSecurityPayloadFrame securityPayload = payloadEncapsulationQueue.poll(); + if (securityPayload == null) { + logger.warn("NODE {}: payloadQueue was empty, returning", this.getNode().getNodeId()); + return; + } + + try { + // empty for the purpose of the test + } catch (ArithmeticException e) { + logger.error("NODE {}: Error in sendNextMessageWithNonce, message not sent", e.toString(), e.getClass()); + } catch (ArrayStoreException e) { + logger.error("NODE {}: Error in sendNextMessageWithNonce, message not sent", e); + } + } +} diff --git a/custom-checks/checkstyle/src/test/resources/checkstyle/exceptionLastParameterCheckTest/CaughtUncheckedExceptionWithValidLogger.java b/custom-checks/checkstyle/src/test/resources/checkstyle/exceptionLastParameterCheckTest/CaughtUncheckedExceptionWithValidLogger.java new file mode 100644 index 00000000..700a47ee --- /dev/null +++ b/custom-checks/checkstyle/src/test/resources/checkstyle/exceptionLastParameterCheckTest/CaughtUncheckedExceptionWithValidLogger.java @@ -0,0 +1,14 @@ +public class CaughtUncheckedExceptionWithValidLogger { + + private CULHandlerInternal createNewHandler(T config) throws CULDeviceException { + try { + // empty for the purpose of the test + } catch (SecurityException e1) { + logger.error(" ... ", e1); + } catch (IllegalArgumentException e) { + logger.error(" ... ", e); + } catch (IllegalAccessException e) { + logger.error(" ... ", e); + } + } +} diff --git a/custom-checks/checkstyle/src/test/resources/checkstyle/exceptionLastParameterCheckTest/CheckedExceptionWithInvalidLogger.java b/custom-checks/checkstyle/src/test/resources/checkstyle/exceptionLastParameterCheckTest/CheckedExceptionWithInvalidLogger.java new file mode 100644 index 00000000..87fcff0b --- /dev/null +++ b/custom-checks/checkstyle/src/test/resources/checkstyle/exceptionLastParameterCheckTest/CheckedExceptionWithInvalidLogger.java @@ -0,0 +1,45 @@ +import java.lang.reflect.Constructor; +import java.lang.reflect.InvocationTargetException; +import java.rmi.AlreadyBoundException; +import java.rmi.activation.ActivationException; +import java.io.IOException; +import java.awt.AWTException; +import java.net.MalformedURLException; +import java.util.prefs.BackingStoreException; +import java.security.acl.AclNotFoundException; +import javax.management.BadAttributeValueExpException; + +import org.omg.CORBA.portable.ApplicationException; + +public class CheckedExceptionWithInvalidLogger { + + @Override + public void updated(Dictionary properties) throws ConfigurationException { + logger.info("Update eBus Binding configuration ..."); + + try { + // empty for the purpose of the test + try { + // empty for the purpose of the test + } catch (AclNotFoundException e) { + logger.error(e.toString(), e); + } catch (ActivationException e) { + logger.error(e.toString(), e); + } catch (AlreadyBoundException e) { + logger.error(e.toString(), e); + } catch (ApplicationException e) { + logger.error(e.toString(), e); + } catch (AWTException e) { + logger.error(e.toString(), e); + } catch (BackingStoreException e) { + logger.error(e.toString(), e); + } catch (BadAttributeValueExpException e) { + logger.error(e.toString(), e); + } + } catch (MalformedURLException e) { + logger.error(e, e.toString()); + } catch (IOException e) { + throw new ConfigurationException("general", e.toString(), e); + } + } +} diff --git a/custom-checks/checkstyle/src/test/resources/checkstyle/exceptionLastParameterCheckTest/ClassWithoutCatchBlock.java b/custom-checks/checkstyle/src/test/resources/checkstyle/exceptionLastParameterCheckTest/ClassWithoutCatchBlock.java new file mode 100644 index 00000000..41eb9bf2 --- /dev/null +++ b/custom-checks/checkstyle/src/test/resources/checkstyle/exceptionLastParameterCheckTest/ClassWithoutCatchBlock.java @@ -0,0 +1,6 @@ +public class ClassWithoutCatchBlock { + + protected synchronized RrdDb getDB(String alias) { + return alias; + } +} diff --git a/custom-checks/checkstyle/src/test/resources/checkstyle/exceptionLastParameterCheckTest/ExceptionsWithLogger.java b/custom-checks/checkstyle/src/test/resources/checkstyle/exceptionLastParameterCheckTest/ExceptionsWithLogger.java new file mode 100644 index 00000000..5d1bb232 --- /dev/null +++ b/custom-checks/checkstyle/src/test/resources/checkstyle/exceptionLastParameterCheckTest/ExceptionsWithLogger.java @@ -0,0 +1,27 @@ +import java.lang.reflect.Constructor; +import java.rmi.activation.ActivationException; +import java.lang.reflect.InvocationTargetException; +import java.util.List; + +public class ExceptionsWithLogger { + + private CULHandlerInternal createNewHandler(T config) throws CULDeviceException { + try { + //empty for the purpose of the test + } catch (SecurityException e1) { + logger.error(" ... ", e1.getMessage()); + } catch (NoSuchMethodException e1) { + logger.error(" ... ", e1.getMessage()); + } catch (IllegalArgumentException e1) { + logger.error(" ... ", e1); + } catch (InstantiationException e1) { + logger.error(" ... ", e1); + } catch (IllegalAccessException e1) { + logger.error(" ... ", e1); + } catch (InvocationTargetException e1) { + logger.error(" ... ", e1); + } catch (ActivationException e1) { + logger.error(" ... ", e1.getMethod()); + } + } +} diff --git a/custom-checks/checkstyle/src/test/resources/checkstyle/exceptionLastParameterCheckTest/InvalidIndirectExceptionOfRuntimeException.java b/custom-checks/checkstyle/src/test/resources/checkstyle/exceptionLastParameterCheckTest/InvalidIndirectExceptionOfRuntimeException.java new file mode 100644 index 00000000..42028ee7 --- /dev/null +++ b/custom-checks/checkstyle/src/test/resources/checkstyle/exceptionLastParameterCheckTest/InvalidIndirectExceptionOfRuntimeException.java @@ -0,0 +1,20 @@ +import java.awt.color.CMMException; +import java.awt.color.ICC_ColorSpace; + +public class InvalidIndirectExceptionOfRuntimeException { + + public void exampleMethod() { + try { + // empty for the purpose of the test + } catch (ClassCastException e) { + iccCS = null; + cbLock.lock(); + logger.trace(e, " exception caught"); + try { + warningOccurred(WARNING_IGNORE_INVALID_ICC); + } finally { + cbLock.unlock(); + } + } + } +} diff --git a/custom-checks/checkstyle/src/test/resources/checkstyle/exceptionLastParameterCheckTest/InvalidLoggedUncheckedException.java b/custom-checks/checkstyle/src/test/resources/checkstyle/exceptionLastParameterCheckTest/InvalidLoggedUncheckedException.java new file mode 100644 index 00000000..eded269b --- /dev/null +++ b/custom-checks/checkstyle/src/test/resources/checkstyle/exceptionLastParameterCheckTest/InvalidLoggedUncheckedException.java @@ -0,0 +1,20 @@ +import java.io.File; +import java.io.IOException; +import java.util.concurrent.RejectedExecutionException; +import java.lang.annotation.AnnotationTypeMismatchException; + +import org.rrd4j.core.RrdDb; + +public class InvalidLoggedUncheckedException { + + protected synchronized RrdDb getDB(String alias) { + try { + // empty for the purpose of the test + } catch (RejectedExecutionException e) { + logger.error("Could not create rrd4j database file '{}': {}", file.getAbsolutePath(), e.getMessage()); + } catch (AnnotationTypeMismatchException ae) { + logger.debug("Could not create rrd4j database file '{}': {}", file.getAbsolutePath(), ae.getMessage()); + } + return db; + } +} diff --git a/custom-checks/checkstyle/src/test/resources/checkstyle/exceptionLastParameterCheckTest/InvalidLogger.java b/custom-checks/checkstyle/src/test/resources/checkstyle/exceptionLastParameterCheckTest/InvalidLogger.java new file mode 100644 index 00000000..9cf8aa08 --- /dev/null +++ b/custom-checks/checkstyle/src/test/resources/checkstyle/exceptionLastParameterCheckTest/InvalidLogger.java @@ -0,0 +1,19 @@ +import java.math.BigDecimal; +import java.math.RoundingMode; +import org.eclipse.smarthome.config.core.ConfigDescriptionParameter; +import java.lang.annotation.AnnotationTypeMismatchException; + +class InvalidLogger extends AbstractNormalizer { + + @Override + public Object doNormalize(Object value) { + try { + // empty for the purpose of the test + } catch (ArithmeticException | NumberFormatException e) { + logger.trace("\"{}\" is not a valid integer number.", e, value); + return value; + } + Logger().trace("Class \"{}\" cannot be converted to an integer number.", value.getClass().getName()); + return value; + } +} diff --git a/custom-checks/checkstyle/src/test/resources/checkstyle/exceptionLastParameterCheckTest/InvalidLoggerMultipleParameters.java b/custom-checks/checkstyle/src/test/resources/checkstyle/exceptionLastParameterCheckTest/InvalidLoggerMultipleParameters.java new file mode 100644 index 00000000..aa589a92 --- /dev/null +++ b/custom-checks/checkstyle/src/test/resources/checkstyle/exceptionLastParameterCheckTest/InvalidLoggerMultipleParameters.java @@ -0,0 +1,24 @@ +import java.math.BigDecimal; + +import org.apache.commons.lang.ArrayUtils; +import org.openhab.binding.zwave.internal.protocol.SerialMessage; +import org.openhab.binding.zwave.internal.protocol.SerialMessage.SerialMessageClass; +import org.openhab.binding.zwave.internal.protocol.SerialMessage.SerialMessagePriority; +import org.openhab.binding.zwave.internal.protocol.SerialMessage.SerialMessageType; +import org.openhab.binding.zwave.internal.protocol.commandclass.ZWaveThermostatSetpointCommandClass.SetpointType; + +public class InvalidLoggerMultipleParameters { + + public SerialMessage setMessage(int scale, SetpointType setpointType, BigDecimal setpoint) { + logger.debug("NODE {}: Creating new message for command THERMOSTAT_SETPOINT_SET", this.getNode().getNodeId()); + + try { + // empty for the purpose of the test + } catch (ArithmeticException e) { + logger.error( + "NODE {}: Got an arithmetic exception converting value {} to a valid Z-Wave value. Ignoring THERMOSTAT_SETPOINT_SET message.", + e, e.getMessage(), this.getNode().getNodeId(), setpoint); + return null; + } + } +} diff --git a/custom-checks/checkstyle/src/test/resources/checkstyle/exceptionLastParameterCheckTest/InvalidLoggerUpperCase.java b/custom-checks/checkstyle/src/test/resources/checkstyle/exceptionLastParameterCheckTest/InvalidLoggerUpperCase.java new file mode 100644 index 00000000..4af172dd --- /dev/null +++ b/custom-checks/checkstyle/src/test/resources/checkstyle/exceptionLastParameterCheckTest/InvalidLoggerUpperCase.java @@ -0,0 +1,27 @@ +import java.util.BitSet; + +import org.apache.commons.lang.StringUtils; +import org.openhab.binding.rpircswitch.internal.RPiRcSwitchBindingConfig; +import org.openhab.core.items.Item; +import org.openhab.core.library.items.SwitchItem; +import org.openhab.model.item.binding.BindingConfigParseException; + +import de.pi3g.pi.rcswitch.RCSwitch; +import javax.lang.model.type.MirroredTypesException; + +public class InvalidLoggerUpperCase { + + @Override + public void processBindingConfiguration(String context, Item item, String bindingConfig) + throws BindingConfigParseException { + try { + // empty for the purpose of the test + } catch (IndexOutOfBoundsException e) { + LOGGER.error("The group address '" + groupAddressString + + "' is invalid. The group address must have 5 bits, e.g. 10101."); + } catch (MirroredTypesException e) { + LOGGER.error("The device address '" + deviceAddressString + + "' is invalid. The device address must be an Integer value, e.g. 4.", e.getClass()); + } + } +} diff --git a/custom-checks/checkstyle/src/test/resources/checkstyle/exceptionLastParameterCheckTest/InvalidLoggerWithMultipleExceptionParameters.java b/custom-checks/checkstyle/src/test/resources/checkstyle/exceptionLastParameterCheckTest/InvalidLoggerWithMultipleExceptionParameters.java new file mode 100644 index 00000000..5333d03c --- /dev/null +++ b/custom-checks/checkstyle/src/test/resources/checkstyle/exceptionLastParameterCheckTest/InvalidLoggerWithMultipleExceptionParameters.java @@ -0,0 +1,31 @@ +import static org.openhab.binding.tesla.TeslaBindingConstants.*; + +import javax.swing.undo.CannotRedoException; + +import java.security.GeneralSecurityException; +import java.text.SimpleDateFormat; +import java.util.Calendar; +import java.util.Date; + +import javax.ws.rs.client.Entity; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; + +import org.apache.commons.lang.StringUtils; +import org.eclipse.smarthome.core.storage.Storage; +import org.eclipse.smarthome.core.thing.ThingStatusDetail; +import org.openhab.binding.tesla.TeslaBindingConstants; +import org.openhab.binding.tesla.internal.protocol.TokenRequestRefreshToken; +import org.openhab.binding.tesla.internal.protocol.TokenResponse; + +public class InvalidLoggerWithMultipleExceptionParameters { + + private ThingStatusDetail authenticate() { + try { + tokenRequest = new TokenRequestRefreshToken(token.refresh_token); + } catch (CannotRedoException e) { + Logger().error("An exception occurred while requesting a new token : '{}'", e, " ... ", e.getMessage()); + } + return ThingStatusDetail.CONFIGURATION_ERROR; + } +} diff --git a/custom-checks/checkstyle/src/test/resources/checkstyle/exceptionLastParameterCheckTest/InvalidLoggerWithMultipleExceptions.java b/custom-checks/checkstyle/src/test/resources/checkstyle/exceptionLastParameterCheckTest/InvalidLoggerWithMultipleExceptions.java new file mode 100644 index 00000000..844c1e26 --- /dev/null +++ b/custom-checks/checkstyle/src/test/resources/checkstyle/exceptionLastParameterCheckTest/InvalidLoggerWithMultipleExceptions.java @@ -0,0 +1,43 @@ +import java.util.Map; + +import java.util.NoSuchElementException; +import javax.xml.bind.TypeConstraintException; + +import org.openhab.binding.mcp23017.internal.MCP23017GenericBindingProvider.MCP23017BindingConfig; +import org.openhab.core.items.Item; +import org.openhab.core.library.items.SwitchItem; +import org.openhab.model.item.binding.BindingConfigParseException; + +import com.json.parsers.JSONParser; +import com.json.parsers.JsonParserFactory; +import com.pi4j.gpio.extension.mcp.MCP23017Pin; +import com.pi4j.io.gpio.Pin; +import com.pi4j.io.gpio.PinMode; +import com.pi4j.io.gpio.PinState; + +public class InvalidLoggerWithMultipleExceptions { + + @Override + public void processBindingConfiguration(String context, Item item, String bindingConfig) { + try { + // empty for the purpose of the test + } catch (NoSuchElementException exception) { + final String message = "Illegal argument exception in configuration string "; + logger.error("{} '{}': {}", message, bindingConfig, exception.getMessage()); + throw new BindingConfigParseException(message + "'" + bindingConfig + "'"); + } catch (ArithmeticException exception) { + final String message = "Illegal access exception in configuration string "; + logger.error("{} '{}': {}", message, bindingConfig, exception.getMessage()); + throw new BindingConfigParseException(message + "'" + bindingConfig + "'"); + } catch (ArrayStoreException exception) { + final String message = "No such field exception in configuration string "; + logger.error("{} '{}': {}", message, bindingConfig, exception.getMessage()); + throw new BindingConfigParseException(message + "'" + bindingConfig + "'"); + } catch (TypeConstraintException exception) { + final String message = "Security exception in configuration string "; + logger.error("{} '{}': {}", message, bindingConfig, exception.getMessage()); + throw new BindingConfigParseException(message + "'" + bindingConfig + "'"); + } + addBindingConfig(item, config); + } +} diff --git a/custom-checks/checkstyle/src/test/resources/checkstyle/exceptionLastParameterCheckTest/LoggerInIfElseStatement.java b/custom-checks/checkstyle/src/test/resources/checkstyle/exceptionLastParameterCheckTest/LoggerInIfElseStatement.java new file mode 100644 index 00000000..6e735478 --- /dev/null +++ b/custom-checks/checkstyle/src/test/resources/checkstyle/exceptionLastParameterCheckTest/LoggerInIfElseStatement.java @@ -0,0 +1,31 @@ +import java.io.IOException; +import java.util.LinkedList; +import java.util.List; + +import org.openhab.binding.dsmr.internal.DSMRPort.PortState; +import org.openhab.binding.dsmr.internal.messages.OBISMessage; + +public class LoggerInIfElseStatement { + + public List read() { + try { + // empty for the purpose of the test + } catch (ArithmeticException ioe) { + if (portState == PortState.CLOSED) { + logger.info("Read aborted: DSMRPort is closed"); + } else { + logger.warn("DSMRPort is not available anymore, closing port"); + logger.debug("Caused by:", ioe, " exception"); + close(); + } + } catch (ArrayStoreException npe) { + if (portState == PortState.CLOSED) { + logger.info("Read aborted: DSMRPort is closed"); + } else { + logger.error("Unexpected problem occured", npe.getClass(), " exception"); + close(); + } + } + return receivedMessages; + } +} diff --git a/custom-checks/checkstyle/src/test/resources/checkstyle/exceptionLastParameterCheckTest/LoggerWithMultipleParametersWithoutException.java b/custom-checks/checkstyle/src/test/resources/checkstyle/exceptionLastParameterCheckTest/LoggerWithMultipleParametersWithoutException.java new file mode 100644 index 00000000..e17d3ce1 --- /dev/null +++ b/custom-checks/checkstyle/src/test/resources/checkstyle/exceptionLastParameterCheckTest/LoggerWithMultipleParametersWithoutException.java @@ -0,0 +1,18 @@ +import java.security.GeneralSecurityException; + +import javax.crypto.Cipher; +import javax.crypto.spec.SecretKeySpec; + +import sun.awt.SunHints.Value; + +public class LoggerWithMultipleParametersWithoutException { + + void setupNetworkKey(boolean useSchemeZero) { + try { + //empty for the purpose of the test + } catch (IllegalStateException e) { + logger.error("NODE " + this.getNode().getNodeId() + ": Error building derived keys", Value.get(5, 10)); + keyException = e; + } + } +} diff --git a/custom-checks/checkstyle/src/test/resources/checkstyle/exceptionLastParameterCheckTest/MultipleCatchBlocksWithInvalidLogger.java b/custom-checks/checkstyle/src/test/resources/checkstyle/exceptionLastParameterCheckTest/MultipleCatchBlocksWithInvalidLogger.java new file mode 100644 index 00000000..bcc227a6 --- /dev/null +++ b/custom-checks/checkstyle/src/test/resources/checkstyle/exceptionLastParameterCheckTest/MultipleCatchBlocksWithInvalidLogger.java @@ -0,0 +1,22 @@ +import static org.apache.commons.lang.StringUtils.capitalize; + +import java.lang.reflect.Field; +import java.lang.reflect.InvocationTargetException; + +public class MultipleCatchBlocksWithInvalidLogger { + + private Object invokeGetter(Field field, Object object) { + try { + // empty for the purpose of the test + } catch (ArithmeticException e) { + logger.trace(" ... ", e.getMessage(), " ... ", e.getClass(), " .... ", test()); + } catch (NumberFormatException e) { + logger.debug("Error getting property value", e); + } catch (SecurityException e) { + logger.debug("Error getting property value", e); + } catch (InvocationTargetException e) { + logger.debug("Error getting property value", e); + } + return null; + } +} diff --git a/custom-checks/checkstyle/src/test/resources/checkstyle/exceptionLastParameterCheckTest/ValidIndirectExceptionOfRuntimeException.java b/custom-checks/checkstyle/src/test/resources/checkstyle/exceptionLastParameterCheckTest/ValidIndirectExceptionOfRuntimeException.java new file mode 100644 index 00000000..28fcad72 --- /dev/null +++ b/custom-checks/checkstyle/src/test/resources/checkstyle/exceptionLastParameterCheckTest/ValidIndirectExceptionOfRuntimeException.java @@ -0,0 +1,19 @@ +import java.text.ParseException; + +import org.eclipse.smarthome.automation.Trigger; +import org.eclipse.smarthome.automation.module.timer.factory.TimerModuleHandlerFactory; +import org.eclipse.smarthome.core.scheduler.ExpressionThreadPoolManager; +import org.eclipse.smarthome.core.scheduler.RecurrenceExpression; +import java.nio.file.DirectoryIteratorException; + +public class ValidIndirectExceptionOfRuntimeException { + + public TimeOfDayTriggerHandler(Trigger module) { + try { + //empty for the purpose of the test + } catch (ArrayIndexOutOfBoundsException | DirectoryIteratorException e) { + logger.trace(e); + } + scheduler = ExpressionThreadPoolManager.getExpressionScheduledPool(TimerModuleHandlerFactory.THREADPOOLNAME); + } +} diff --git a/custom-checks/checkstyle/src/test/resources/checkstyle/exceptionLastParameterCheckTest/ValidLoggerMultipleParameters.java b/custom-checks/checkstyle/src/test/resources/checkstyle/exceptionLastParameterCheckTest/ValidLoggerMultipleParameters.java new file mode 100644 index 00000000..0d89c861 --- /dev/null +++ b/custom-checks/checkstyle/src/test/resources/checkstyle/exceptionLastParameterCheckTest/ValidLoggerMultipleParameters.java @@ -0,0 +1,19 @@ +import java.util.List; +import java.util.Set; + +import org.eclipse.smarthome.automation.Rule; + +public class ValidLoggerMultipleParameters { + + @Override + protected void addNewProvidedObjects(List newPortfolio, List previousPortfolio, + Set parsedObjects) { + try { + // empty for the purpose of the test + } catch (IllegalArgumentException e) { + logger.debug("Not importing rule '{}' because: {}", rule.getUID(), e.getMessage(), e); + } catch (IllegalStateException e) { + logger.debug("Not importing rule '{}' since the rule registry is in an invalid state: {}", rule.getUID(), e.getMessage()); + } + } +} \ No newline at end of file diff --git a/custom-checks/checkstyle/src/test/resources/checkstyle/exceptionLastParameterCheckTest/ValidLoggerWihtMultipleCatch.java b/custom-checks/checkstyle/src/test/resources/checkstyle/exceptionLastParameterCheckTest/ValidLoggerWihtMultipleCatch.java new file mode 100644 index 00000000..60da567b --- /dev/null +++ b/custom-checks/checkstyle/src/test/resources/checkstyle/exceptionLastParameterCheckTest/ValidLoggerWihtMultipleCatch.java @@ -0,0 +1,32 @@ +import java.util.UUID; + +import org.openhab.action.ciscospark.internal.CiscoSparkActionService; +import org.openhab.core.scriptengine.action.ActionDoc; +import org.openhab.core.scriptengine.action.ParamDoc; + +import com.ciscospark.Message; +import com.ciscospark.SparkException; + +public class ValidLoggerWihtMultipleCatch { + + public static boolean sparkMessage(@ParamDoc(name = "msgTxt", text = "the Message to send") String msgTxt, + @ParamDoc(name = "roomId", text = "the Room to which to send") String roomId) { + try { + UUID.fromString(roomId); + } catch (IllegalArgumentException e) { + logger.warn("Room id is not a UUID"); + return false; + } + + try { + logger.debug("Creating message"); + return true; + } catch (IllegalStateException se) { + logger.warn("Failed to send message.", se); + return false; + } catch (Exception e) { + logger.warn("Failed to send message!", e); + return false; + } + } +} diff --git a/custom-checks/checkstyle/src/test/resources/checkstyle/exceptionLastParameterCheckTest/ValidMultipleExceptions.java b/custom-checks/checkstyle/src/test/resources/checkstyle/exceptionLastParameterCheckTest/ValidMultipleExceptions.java new file mode 100644 index 00000000..dbc1eb1b --- /dev/null +++ b/custom-checks/checkstyle/src/test/resources/checkstyle/exceptionLastParameterCheckTest/ValidMultipleExceptions.java @@ -0,0 +1,43 @@ +import java.io.IOException; +import java.nio.BufferOverflowException; +import java.util.concurrent.Executors; + +import org.openhab.binding.ebus.internal.EBusTelegram; +import org.openhab.binding.ebus.internal.connection.WorkerThreadFactory; +import javax.lang.model.UnknownEntityException; +import java.lang.invoke.WrongMethodTypeException; +import java.util.ConcurrentModificationException; +import java.awt.geom.IllegalPathStateException; + +public class ValidMultipleExceptions { + + @Override + public void run() { + try { + // empty for the purpose of the test + } catch (ArithmeticException e) { + logger.error("An IO exception has occured! Try to reconnect eBus connector ...", e); + + try { + reconnect(); + } catch (NumberFormatException e1) { + logger.error(e.toString(), e1); + } catch (UnknownEntityException e1) { + logger.error(e.toString(), e1); + } + + } catch (WrongMethodTypeException e) { + logger.error("eBUS telegram buffer overflow - not enough sync bytes received! Try to adjust eBus adapter."); + inputBuffer.clear(); + + } catch (ConcurrentModificationException e) { + logger.error(e.toString(), e); + Thread.currentThread().interrupt(); + inputBuffer.clear(); + + } catch (IllegalPathStateException e) { + logger.error(e.toString(), e); + inputBuffer.clear(); + } + } +} diff --git a/sat-plugin/src/main/resources/rulesets/checkstyle/rules.xml b/sat-plugin/src/main/resources/rulesets/checkstyle/rules.xml index ae14a67c..4d63e4af 100644 --- a/sat-plugin/src/main/resources/rulesets/checkstyle/rules.xml +++ b/sat-plugin/src/main/resources/rulesets/checkstyle/rules.xml @@ -215,6 +215,10 @@ + + + +