Skip to content

Refactor loggers and make Checker a final, non abstract class #67

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Sep 4, 2015
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 5 additions & 8 deletions src/main/java/de/thetaphi/forbiddenapis/AbstractCheckMojo.java
Original file line number Diff line number Diff line change
Expand Up @@ -215,22 +215,19 @@ public void execute() throws MojoExecutionException, MojoFailureException {
if (failOnMissingClasses) options.add(FAIL_ON_MISSING_CLASSES);
if (failOnViolation) options.add(FAIL_ON_VIOLATION);
if (failOnUnresolvableSignatures) options.add(FAIL_ON_UNRESOLVABLE_SIGNATURES);
final Checker checker = new Checker(loader, options) {
@Override
protected void logError(String msg) {
final Checker checker = new Checker(new Logger() {
public void error(String msg) {
log.error(msg);
}

@Override
protected void logWarn(String msg) {
public void warn(String msg) {
log.warn(msg);
}

@Override
protected void logInfo(String msg) {
public void info(String msg) {
log.info(msg);
}
};
}, loader, options);

if (!checker.isSupportedJDK) {
final String msg = String.format(Locale.ENGLISH,
Expand Down
13 changes: 5 additions & 8 deletions src/main/java/de/thetaphi/forbiddenapis/AntTask.java
Original file line number Diff line number Diff line change
Expand Up @@ -85,23 +85,20 @@ public void execute() throws BuildException {
if (failOnMissingClasses) options.add(FAIL_ON_MISSING_CLASSES);
if (failOnViolation) options.add(FAIL_ON_VIOLATION);
if (failOnUnresolvableSignatures) options.add(FAIL_ON_UNRESOLVABLE_SIGNATURES);
final Checker checker = new Checker(loader, options) {
@Override
protected void logError(String msg) {
final Checker checker = new Checker(new Logger() {
public void error(String msg) {
log(msg, Project.MSG_ERR);
}

@Override
protected void logWarn(String msg) {
public void warn(String msg) {
// ANT has no real log levels printed, so prefix with "WARNING":
log("WARNING: " + msg, Project.MSG_WARN);
}

@Override
protected void logInfo(String msg) {
public void info(String msg) {
log(msg, Project.MSG_INFO);
}
};
}, loader, options);

if (!checker.isSupportedJDK) {
final String msg = String.format(Locale.ENGLISH,
Expand Down
25 changes: 12 additions & 13 deletions src/main/java/de/thetaphi/forbiddenapis/Checker.java
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@
* and the system classloader. It uses the local classpath in preference to the system classpath
* (which violates the spec).
*/
public abstract class Checker implements RelatedClassLookup {
public final class Checker implements RelatedClassLookup {

public static enum Option {
INTERNAL_RUNTIME_FORBIDDEN,
Expand All @@ -69,6 +69,8 @@ public static enum Option {

private final long start;

final Logger logger;

final Set<File> bootClassPathJars;
final Set<String> bootClassPathDirs;
final ClassLoader loader;
Expand All @@ -90,15 +92,12 @@ public static enum Option {
// descriptors (not internal names) of all annotations that suppress:
final Set<String> suppressAnnotations = new LinkedHashSet<String>();

protected abstract void logError(String msg);
protected abstract void logWarn(String msg);
protected abstract void logInfo(String msg);

public Checker(ClassLoader loader, Option... options) {
this(loader, (options.length == 0) ? EnumSet.noneOf(Option.class) : EnumSet.copyOf(Arrays.asList(options)));
public Checker(Logger logger, ClassLoader loader, Option... options) {
this(logger, loader, (options.length == 0) ? EnumSet.noneOf(Option.class) : EnumSet.copyOf(Arrays.asList(options)));
}

public Checker(ClassLoader loader, EnumSet<Option> options) {
public Checker(Logger logger, ClassLoader loader, EnumSet<Option> options) {
this.logger = logger;
this.loader = loader;
this.options = options;
this.start = System.currentTimeMillis();
Expand Down Expand Up @@ -228,7 +227,7 @@ public ClassSignature lookupRelatedClass(String internalName) {
if (options.contains(Option.FAIL_ON_MISSING_CLASSES)) {
throw new WrapperRuntimeException(cnfe);
} else {
logWarn(String.format(Locale.ENGLISH,
logger.warn(String.format(Locale.ENGLISH,
"The referenced class '%s' cannot be loaded. Please fix the classpath!",
type.getClassName()
));
Expand All @@ -241,7 +240,7 @@ private void reportParseFailed(boolean failOnUnresolvableSignatures, String mess
if (failOnUnresolvableSignatures) {
throw new ParseException(String.format(Locale.ENGLISH, "%s while parsing signature: %s", message, signature));
} else {
logWarn(String.format(Locale.ENGLISH, "%s while parsing signature: %s [signature ignored]", message, signature));
logger.warn(String.format(Locale.ENGLISH, "%s while parsing signature: %s [signature ignored]", message, signature));
}
}

Expand Down Expand Up @@ -428,7 +427,7 @@ private int checkClass(final ClassReader reader, Pattern suppressAnnotationsPatt
final Pattern splitter = Pattern.compile(Pattern.quote("\n"));
for (final ForbiddenViolation v : violations) {
for (final String line : splitter.split(v.format(className, scanner.getSourceFile()))) {
logError(line);
logger.error(line);
}
}
return violations.size();
Expand All @@ -450,10 +449,10 @@ public final void run() throws ForbiddenApiException {
"Scanned %d (and %d related) class file(s) for forbidden API invocations (in %.2fs), %d error(s).",
classesToCheck.size(), classesToCheck.isEmpty() ? 0 : classpathClassCache.size(), (System.currentTimeMillis() - start) / 1000.0, errors);
if (options.contains(Option.FAIL_ON_VIOLATION) && errors > 0) {
logError(message);
logger.error(message);
throw new ForbiddenApiException("Check for forbidden API calls failed, see log.");
} else {
logInfo(message);
logger.info(message);
}
}

Expand Down
46 changes: 9 additions & 37 deletions src/main/java/de/thetaphi/forbiddenapis/CliMain.java
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,8 @@ public final class CliMain {
internalruntimeforbiddenOpt, allowmissingclassesOpt, allowunresolvablesignaturesOpt, versionOpt, helpOpt;
private final CommandLine cmd;

private static final Logger LOG = StdIoLogger.INSTANCE;

public static final int EXIT_SUCCESS = 0;
public static final int EXIT_VIOLATION = 1;
public static final int EXIT_ERR_CMDLINE = 2;
Expand Down Expand Up @@ -148,24 +150,9 @@ public CliMain(String... args) throws ExitException {
}
}

@SuppressForbidden
void logError(String msg) {
System.err.println("ERROR: " + msg);
}

@SuppressForbidden
void logWarn(String msg) {
System.err.println("WARNING: " + msg);
}

@SuppressForbidden
void logInfo(String msg) {
System.out.println(msg);
}

private void printVersion() {
final Package pkg = this.getClass().getPackage();
logInfo(String.format(Locale.ENGLISH,
LOG.info(String.format(Locale.ENGLISH,
"%s %s",
pkg.getImplementationTitle(), pkg.getImplementationVersion()
));
Expand Down Expand Up @@ -227,22 +214,7 @@ public void run() throws ExitException {
if (cmd.hasOption(internalruntimeforbiddenOpt.getLongOpt())) options.add(INTERNAL_RUNTIME_FORBIDDEN);
if (!cmd.hasOption(allowmissingclassesOpt.getLongOpt())) options.add(FAIL_ON_MISSING_CLASSES);
if (!cmd.hasOption(allowunresolvablesignaturesOpt.getLongOpt())) options.add(FAIL_ON_UNRESOLVABLE_SIGNATURES);
final Checker checker = new Checker(loader, options) {
@Override
protected void logError(String msg) {
CliMain.this.logError(msg);
}

@Override
protected void logWarn(String msg) {
CliMain.this.logWarn(msg);
}

@Override
protected void logInfo(String msg) {
CliMain.this.logInfo(msg);
}
};
final Checker checker = new Checker(LOG, loader, options);

if (!checker.isSupportedJDK) {
throw new ExitException(EXIT_UNSUPPORTED_JDK, String.format(Locale.ENGLISH,
Expand All @@ -255,7 +227,7 @@ protected void logInfo(String msg) {
checker.addSuppressAnnotation(a);
}

logInfo("Scanning for classes to check...");
LOG.info("Scanning for classes to check...");
if (!classesDirectory.exists()) {
throw new ExitException(EXIT_ERR_OTHER, "Directory with class files does not exist: " + classesDirectory);
}
Expand All @@ -281,13 +253,13 @@ protected void logInfo(String msg) {
try {
final String[] bundledSignatures = cmd.getOptionValues(bundledsignaturesOpt.getLongOpt());
if (bundledSignatures != null) for (String bs : bundledSignatures) {
logInfo("Reading bundled API signatures: " + bs);
LOG.info("Reading bundled API signatures: " + bs);
checker.parseBundledSignatures(bs, null);
}
final String[] signaturesFiles = cmd.getOptionValues(signaturesfileOpt.getLongOpt());
if (signaturesFiles != null) for (String sf : signaturesFiles) {
final File f = new File(sf).getAbsoluteFile();
logInfo("Reading API signatures: " + f);
LOG.info("Reading API signatures: " + f);
checker.parseSignaturesFile(new FileInputStream(f));
}
} catch (IOException ioe) {
Expand All @@ -303,7 +275,7 @@ protected void logInfo(String msg) {
));
}

logInfo("Loading classes to check...");
LOG.info("Loading classes to check...");
try {
for (String f : files) {
checker.addClassToCheck(new FileInputStream(new File(classesDirectory, f)));
Expand All @@ -312,7 +284,7 @@ protected void logInfo(String msg) {
throw new ExitException(EXIT_ERR_OTHER, "Failed to load one of the given class files: " + ioe);
}

logInfo("Scanning for API signatures and dependencies...");
LOG.info("Scanning for API signatures and dependencies...");
try {
checker.run();
} catch (ForbiddenApiException fae) {
Expand Down
23 changes: 23 additions & 0 deletions src/main/java/de/thetaphi/forbiddenapis/Logger.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package de.thetaphi.forbiddenapis;

/*
* (C) Copyright Uwe Schindler (Generics Policeman) and others.
*
* 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.
*/

public interface Logger {
abstract void error(String msg);
abstract void warn(String msg);
abstract void info(String msg);
}
38 changes: 38 additions & 0 deletions src/main/java/de/thetaphi/forbiddenapis/StdIoLogger.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
package de.thetaphi.forbiddenapis;

/*
* (C) Copyright Uwe Schindler (Generics Policeman) and others.
*
* 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.
*/

@SuppressForbidden
public final class StdIoLogger implements Logger {

public static final Logger INSTANCE = new StdIoLogger();

private StdIoLogger() {}

public void error(String msg) {
System.err.println("ERROR: " + msg);
}

public void warn(String msg) {
System.err.println("WARNING: " + msg);
}

public void info(String msg) {
System.out.println(msg);
}

}
30 changes: 2 additions & 28 deletions src/test/java/de/thetaphi/forbiddenapis/CheckerSetupTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -28,33 +28,11 @@

public final class CheckerSetupTest {

@SuppressForbidden
static final class MyChecker extends Checker {
public MyChecker() {
super(ClassLoader.getSystemClassLoader(), INTERNAL_RUNTIME_FORBIDDEN, FAIL_ON_MISSING_CLASSES, FAIL_ON_VIOLATION, FAIL_ON_UNRESOLVABLE_SIGNATURES);
}

@Override
protected void logError(String msg) {
System.err.println("ERROR: " + msg);
}

@Override
protected void logWarn(String msg) {
System.err.println("WARN: " + msg);
}

@Override
protected void logInfo(String msg) {
System.err.println(msg);
}
}

protected Checker checker;

@Before
public void setUp() {
checker = new MyChecker();
checker = new Checker(StdIoLogger.INSTANCE, ClassLoader.getSystemClassLoader(), INTERNAL_RUNTIME_FORBIDDEN, FAIL_ON_MISSING_CLASSES, FAIL_ON_VIOLATION, FAIL_ON_UNRESOLVABLE_SIGNATURES);
assumeTrue("This test only works with a supported JDK (see docs)", checker.isSupportedJDK);
assertEquals(EnumSet.of(INTERNAL_RUNTIME_FORBIDDEN, FAIL_ON_MISSING_CLASSES, FAIL_ON_VIOLATION, FAIL_ON_UNRESOLVABLE_SIGNATURES), checker.options);
}
Expand Down Expand Up @@ -105,11 +83,7 @@ public void testMethodSignature() throws Exception {

@Test
public void testEmptyCtor() throws Exception {
Checker chk = new Checker(ClassLoader.getSystemClassLoader()) {
@Override protected void logError(String msg) { }
@Override protected void logWarn(String msg) { }
@Override protected void logInfo(String msg) { }
};
Checker chk = new Checker(StdIoLogger.INSTANCE, ClassLoader.getSystemClassLoader());
assertEquals(EnumSet.noneOf(Checker.Option.class), chk.options);
}

Expand Down