/* * Copyright 2012 - 2014 Maginatics, Inc. * * Licensed 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 com.maginatics.jdbclint; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.PrintStream; import java.sql.SQLException; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.EnumSet; import java.util.Set; /** * Configuration for JDBC lint. Most users should use * Configuration.DEFAULT_CHECKS which provides sane defaults. */ public final class Configuration { /** JDBC lint checks. */ public enum Check { BLOB_DOUBLE_FREE, BLOB_MISSING_FREE, CONNECTION_DOUBLE_CLOSE, CONNECTION_MISSING_CLOSE, CONNECTION_MISSING_COMMIT_OR_ROLLBACK, CONNECTION_MISSING_PREPARE_STATEMENT, CONNECTION_MISSING_READ_ONLY, PREPARED_STATEMENT_DOUBLE_CLOSE, PREPARED_STATEMENT_MISSING_CLOSE, PREPARED_STATEMENT_MISSING_EXECUTE, PREPARED_STATEMENT_MISSING_EXECUTE_BATCH, RESULT_SET_DOUBLE_CLOSE, RESULT_SET_MISSING_CLOSE, RESULT_SET_UNREAD_COLUMN, STATEMENT_DOUBLE_CLOSE, STATEMENT_MISSING_CLOSE, STATEMENT_MISSING_EXECUTE, STATEMENT_MISSING_EXECUTE_BATCH; } private final Set<Check> checks; public static final Set<Check> DEFAULT_CHECKS = Collections.unmodifiableSet(EnumSet.complementOf(EnumSet.of( Check.CONNECTION_MISSING_READ_ONLY))); /** Action to take after failing a check. */ public interface Action { void apply(String message, Exception exception) throws SQLException; } private final Collection<Action> actions; public static final Action PRINT_STACK_TRACE_ACTION = new Action() { @Override public void apply(final String message, final Exception exception) { new SQLException(message, exception).printStackTrace(); } }; public static final Action SYSTEM_EXIT_ACTION = new Action() { @Override public void apply(final String message, final Exception exception) { System.exit(1); } }; public static final Action THROW_RUNTIME_EXCEPTION_ACTION = new Action() { @Override public void apply(final String message, final Exception exception) { throw new RuntimeException(message, exception); } }; public static final Action THROW_SQL_EXCEPTION_ACTION = new Action() { @Override public void apply(final String message, final Exception exception) throws SQLException { throw new SQLException(message, exception); } }; public static Action printStackTraceToFile(final File file) { Utils.checkNotNull(file); return new Action() { @Override public void apply(final String message, final Exception exception) { PrintStream ps = null; try { ps = new PrintStream(new FileOutputStream(file), /*append=*/ true); ps.println(message); new SQLException(exception).printStackTrace(ps); } catch (IOException ioe) { throw new RuntimeException(ioe); } finally { if (ps != null) { ps.close(); } } } }; } public Configuration(final Set<Check> checks, final Collection<Action> actions) { this.checks = Collections.unmodifiableSet(EnumSet.copyOf( Utils.checkNotNull(checks))); this.actions = Collections.unmodifiableCollection( new ArrayList<Action>(Utils.checkNotNull(actions))); } public boolean isEnabled(final Check check) { return checks.contains(Utils.checkNotNull(check)); } public Set<Check> getChecks() { return checks; } public Collection<Action> getActions() { return actions; } }