Skip to content

Commit

Permalink
Issue #3497: Split Guard class in two
Browse files Browse the repository at this point in the history
  • Loading branch information
jochenvdv committed Oct 23, 2016
1 parent 0e7beca commit ed508ef
Show file tree
Hide file tree
Showing 12 changed files with 492 additions and 345 deletions.
@@ -0,0 +1,94 @@
////////////////////////////////////////////////////////////////////////////////
// checkstyle: Checks Java source code for adherence to a set of rules.
// Copyright (C) 2001-2016 the original author or authors.
//
// This library 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 2.1 of the License, or (at your option) any later version.
//
// This library 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 library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
////////////////////////////////////////////////////////////////////////////////

package com.puppycrawl.tools.checkstyle.checks.imports;

/**
* Base class for import rules.
* @author Jochen Van de Velde
*/
abstract class AbstractImportRule {
/** Indicates whether to allow access or not. */
private final boolean allowed;

/** Indicates if the guard only applies to this package. */
private final boolean localOnly;

/**
* Indicates if the name is to be interpreted
* as a regular expression.
*/
private final boolean regExp;

/**
* Constructs an instance.
* @param allow whether to allow access.
* @param localOnly whether the rules is to be applied locally only.
* @param regExp whether the name is to be interpreted as a regular
* expression.
*/
protected AbstractImportRule(final boolean allow, final boolean localOnly,
final boolean regExp) {
allowed = allow;
this.localOnly = localOnly;
this.regExp = regExp;
}

/**
* Verifies whether a package name is used.
* @param forImport the import to check.
* @return a result {@link AccessResult} indicating whether it can be used.
*/
public abstract AccessResult verifyImport(String forImport);

/**
* @return whether the guard is to only be applied locally.
*/
public boolean isLocalOnly() {
return localOnly;
}

/**
* @return whether the name is to be interpreted as a regular expression.
*/
protected boolean isRegExp() {
return regExp;
}

/**
* Returns the appropriate {@link AccessResult} based on whether there
* was a match and if the rule is to allow access.
* @param matched indicates whether there was a match.
* @return An appropriate {@link AccessResult}.
*/
protected AccessResult calculateResult(final boolean matched) {
AccessResult result = AccessResult.UNKNOWN;

if (matched) {
if (allowed) {
result = AccessResult.ALLOWED;
}
else {
result = AccessResult.DISALLOWED;
}
}

return result;
}
}
@@ -0,0 +1,62 @@
////////////////////////////////////////////////////////////////////////////////
// checkstyle: Checks Java source code for adherence to a set of rules.
// Copyright (C) 2001-2016 the original author or authors.
//
// This library 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 2.1 of the License, or (at your option) any later version.
//
// This library 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 library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
////////////////////////////////////////////////////////////////////////////////

package com.puppycrawl.tools.checkstyle.checks.imports;

/**
* Represents whether a class is allowed to be imported or not.
* @author Oliver Burn
*/
class ClassImportRule extends AbstractImportRule {
/** Package to control access to. */
private final String className;

/**
* Constructs an instance.
* @param allow whether to allow access.
* @param localOnly whether the rule is to be applied locally only
* @param className the class to apply the rule on.
* @param regExp whether the class name is to be interpreted as a regular
* expression.
*/
ClassImportRule(final boolean allow, final boolean localOnly,
final String className, final boolean regExp) {
super(allow, localOnly, regExp);
this.className = className;
}

/**
* Verifies whether a class name is used.
* @param forImport the import to check.
* @return a result {@link AccessResult} indicating whether it can be used.
*/
@Override
public AccessResult verifyImport(final String forImport) {
final boolean classMatch;

if (isRegExp()) {
classMatch = forImport.matches(className);
}
else {
classMatch = forImport.equals(className);
}

return calculateResult(classMatch);
}
}

This file was deleted.

Expand Up @@ -112,21 +112,19 @@ else if (ALLOW_ELEMENT_NAME.equals(qName) || "disallow".equals(qName)) {
final boolean isLocalOnly = attributes.getValue("local-only") != null;
final String pkg = attributes.getValue(PKG_ATTRIBUTE_NAME);
final boolean regex = containsRegexAttribute(attributes);
final Guard guard;
final AbstractImportRule rule;
if (pkg == null) {
// handle class names which can be normal class names or regular
// expressions
final String clazz = safeGet(attributes, "class");
guard = new Guard(isAllow, isLocalOnly, clazz, regex);
rule = new ClassImportRule(isAllow, isLocalOnly, clazz, regex);
}
else {
final boolean exactMatch =
attributes.getValue("exact-match") != null;
guard = new Guard(isAllow, isLocalOnly, pkg, exactMatch, regex);
rule = new PkgImportRule(isAllow, isLocalOnly, pkg, exactMatch, regex);
}

final PkgControl pkgControl = stack.peek();
pkgControl.addGuard(guard);
stack.peek().addImportRule(rule);
}
}

Expand Down
Expand Up @@ -39,8 +39,8 @@ class PkgControl {
private static final Pattern DOT_PATTERN = Pattern.compile(DOT, Pattern.LITERAL);
/** The regex for the package separator: "\\.". */
private static final String DOT_REGEX = "\\.";
/** List of {@link Guard} objects to check. */
private final Deque<Guard> guards = new LinkedList<>();
/** List of {@link AbstractImportRule} objects to check. */
private final Deque<AbstractImportRule> rules = new LinkedList<>();
/** List of children {@link PkgControl} objects. */
private final List<PkgControl> children = new ArrayList<>();
/** The parent. Null indicates we are the root node. */
Expand Down Expand Up @@ -180,11 +180,11 @@ private static Pattern createPatternForExactMatch(String expression) {
}

/**
* Adds a guard to the node.
* @param thug the guard to be added.
* Adds a {@link AbstractImportRule} to the node.
* @param rule the rule to be added.
*/
protected void addGuard(final Guard thug) {
guards.addFirst(thug);
protected void addImportRule(final AbstractImportRule rule) {
rules.addFirst(rule);
}

/**
Expand Down Expand Up @@ -265,20 +265,20 @@ else if (parent == null) {
}

/**
* Checks whether any of the guards for this node control access to
* a specified package.
* @param forImport the package to check.
* Checks whether any of the rules for this node control access to
* a specified package or class.
* @param forImport the import to check.
* @param inPkg the package doing the import.
* @return an {@link AccessResult}.
*/
private AccessResult localCheckAccess(final String forImport,
final String inPkg) {
for (Guard g : guards) {
// Check if a Guard is only meant to be applied locally.
if (g.isLocalOnly() && !matchesExactly(inPkg)) {
for (AbstractImportRule r : rules) {
// Check if a PkgImportRule is only meant to be applied locally.
if (r.isLocalOnly() && !matchesExactly(inPkg)) {
continue;
}
final AccessResult result = g.verifyImport(forImport);
final AccessResult result = r.verifyImport(forImport);
if (result != AccessResult.UNKNOWN) {
return result;
}
Expand Down

0 comments on commit ed508ef

Please sign in to comment.