Checkstyle rule to limit interactions between root packages (with ImportControl?)

南笙酒味 提交于 2019-12-02 03:33:22

问题


How can I create a Checkstyle rule to limit interactions between different root packages?

I have the following 3 root packages:

  • models
  • views
  • controllers

(They are not something like com.mycompany.myproject.models. They are root packages.)

I wanted to disallow access from models to views and from views to models (and some others).

I try to use the ImportControl-Checker from Checkstyle:

  • Try 1: Use one single import-control.xml. Problem: I can provide only one Root-XML-Element (<import-control pkg="models">) and this contains only one Package (but I want to have more than one).
  • Try 2: Use several import-control.xml. Problem: If I import more than one in checkstyle-config.xml, neither seems to work (there is no error, it just looks like I didn't define neither). My definition in 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>
    

回答1:


Unfortunately, what you want is very hard to do using the ImportControl check out of the box.
Here's why:

You already found out why your option 1 cannot work: There can only be one root package.

Option 2 is possible, but laborious. Let me go into some depth. I used the following two import control files, which disallow using models from views and views from 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>

In my test setup, this basically worked, but there is a drawback: Every class gets a Checkstyle warning that the Import control file does not handle this package. This is because the ImportControl check expects all packages to reside under a common root (verified by looking at the Checkstyle 5.6 sources). So in the models package, you get the warning from the check instance configured for the views package, and vice versa.
There is also the added problem that the ImportControl check only works on the import statements, but does not find fully qualified references used directly in the code.

So, what can you do?

  • Change your app so that you have a common root. This is best practice and generally a good idea.
  • Implement a custom check as a subclass of ImportControlCheck which adds an option for enabling/disabling the "Import control file does not handle this package" message, and otherwise go with your option 2.
  • If you are using Eclipse, there is also a third solution. You could use the advanced configuration dialog that the Checkstyle Eclipse plugin provides in order to restrict the ImportControl instances to their respective files. This would also eliminate the "Import control file does not handle this package" messages.


来源:https://stackoverflow.com/questions/16142898/checkstyle-rule-to-limit-interactions-between-root-packages-with-importcontrol

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!