Checkstyle规则限制根包之间的交互(使用ImportControl?)

时间:2013-04-22 08:48:10

标签: java checkstyle

如何创建Checkstyle规则以限制不同根包之间的交互?

我有以下3个根包:

  • models
  • views
  • controllers

(他们不是类似于com.mycompany.myproject.models。他们是根软件包。)

我想禁止从modelsviews以及viewsmodels(以及其他一些人)的访问。

我尝试使用Checkstyle中的ImportControl-Checker

  • 尝试1:使用一个import-control.xml。问题:我只能提供一个Root-XML-Element(<import-control pkg="models">),它只包含一个Package(但我希望有多个)。
  • 尝试2:使用多个import-control.xml。问题:如果我在checkstyle-config.xml中导入多个,似乎都不起作用(没有错误,它看起来我没有定义)。我在import-control.xml中的定义:

    <module name="ImportControl">
      <property name="id" value="ImportControlViews"/>
      <property name="file" value="${basedir}/project/import-control/views.xml"/>
    </module>
    <module name="ImportControl">
      <property name="id" value="ImportControlModels"/>
      <property name="file" value="${basedir}/project/import-control/models.xml"/>
    </module>
    

2 个答案:

答案 0 :(得分:1)

不幸的是,你想要的东西很难用于开箱即用的ImportControl。这就是原因:

您已经找到了为什么您的选项1无法工作:只能有一个根包。

选项2是可能的,但很费力。让我深入一点。我使用了以下两个导入控制文件,这些文件禁止使用models中的viewsviews中的models

<!DOCTYPE import-control PUBLIC "-//Puppy Crawl//DTD Import Control 1.1//EN"
    "http://www.puppycrawl.com/dtds/import_control_1_1.dtd">
<import-control pkg="views">
    <allow pkg="views" />
    <disallow pkg="models" />
</import-control>
<!DOCTYPE import-control PUBLIC "-//Puppy Crawl//DTD Import Control 1.1//EN"
    "http://www.puppycrawl.com/dtds/import_control_1_1.dtd">
<import-control pkg="models">
    <allow pkg="models" />
    <disallow pkg="views" />
</import-control>

在我的测试设置中,这基本上有效,但有一个缺点:每个类都会收到一个Checkstyle警告,指出导入控制文件不处理此包。这是因为ImportControl检查要求所有包都驻留在公共根目录下(通过查看Checkstyle 5.6源代码进行验证)。因此,在models包中,您会从为views包配置的检查实例中收到警告,反之亦然。
还有一个问题是ImportControl检查仅适用于import语句,但没有找到直接在代码中使用的完全限定引用。

那么,你能做什么?

  • 更改您的应用,以便拥有共同的根目录。这是最佳做法,通常是一个好主意。
  • 将自定义检查实现为ImportControlCheck的子类,其中添加了启用/禁用“导入控制文件不处理此包”消息的选项,否则请选择其他选项2。
  • 如果您使用的是Eclipse,还有第三种解决方案。您可以使用Checkstyle Eclipse插件提供的高级配置对话框,以便将ImportControl实例限制为各自的文件。这也将消除“导入控制文件不处理此包”消息。

答案 1 :(得分:1)

您可以通过混合构建工具配置和 checkstyle 配置来实现这一点。例如,使用 gradle,您可以将源放在单独的源集中,并使用

checkStyleModels {
    excludes = ['views/**']
    configFile file('checkstyle-models.xml')
}
checkStyleViews {
    excludes = ['models/**']
    configFile file('checkstyle-views.xml')
}

然后在 checkstyle-models.xml 中禁止视图。 两个配置都可以有不同的根目录,没有问题。