Client MVVM is one of the key features in the upcoming ZK 10, which reduces memory footprint and improves response time by moving data binding from the server side to the client side. While the upgrade from Server MVVM to Client MVVM is usually a straightforward process that requires no modification to existing code, certain Server MVVM usages require some alterations due to the nature of the client side.

To facilitate a smooth transition to Client MVVM, ZK Team has developed ZK Client MVVM Linter — a tool specifically designed for identifying potential compatibility issues in Server MVVM files before upgrading. In this blog post, we will guide you through the entire process of setting up and running the linter, covering everything from basic configuration to advanced customization.

Basic Configuration

To run the linter on your project, follow these steps:

  • Clone the zk-client-mvvm-linter-starter repository from our zkoss-demo page.
  • Open the app.properties file in the root directory of the cloned repository and set the zulDir and javaDir properties to relative paths to your Zul and Java source directories.
  • Open your terminal and execute ./gradlew runLinter in the root directory of the cloned repository. The linter will analyze your project and report potential compatibility issues.
  • Review the reported issues and make decisions best suited for your project, whether that means keeping your existing Server MVVM code or making modifications required for upgrading to Client MVVM.

Sample result from running the linter on F86-ZK-4028.zul and B86-ZK-4211.zul:

INFO: --------------------------------------------------------------------------- 
INFO: Checking /zk/zktest/src/main/webapp/test2/F86-ZK-4028.zul 
INFO: /zk/zktest/src/main/webapp/test2/F86-ZK-4028.zul 
WARNING:  108: 25       Zul files supplied via path binding not checked 
INFO: --------------------------------------------------------------------------- 
INFO: Checking /zk/zktest/src/main/webapp/test2/B86-ZK-4211.zul 
INFO: /zk/zktest/src/main/webapp/test2/B86-ZK-4211.zul 
WARNING:   36: 10       ViewModel without fully-qualified class name not checked 
INFO: ---------------------------------------------------------------------------
  • The linter did not find any incompatibility. However, while the linter covers most scenarios, manual checks might still be necessary for certain cases. Please manually check those Zul or Java files against the lint rules listed in the RULES.md file.

Sample result from running the linter on F00633.zul:

INFO: --------------------------------------------------------------------
INFO: Checking /zk/zktest/src/main/webapp/bind/issue/F00633.zul
INFO: /zk/zktest/src/main/webapp/bind/issue/F00633.zul
WARNING:   22: 22       onClick="..." should be @command
INFO: /zk/zktest/src/main/java/org/zkoss/zktest/bind/issue/F00633.java
WARNING:   69: 13       `@ContextParam(ContextType.BINDER)` not supported
WARNING:   90: 28       `@BindingParam Label` not supported
WARNING:   95: 24       `Object` type casting not supported
WARNING:  105: 26       `@BindingParam Label` not supported
INFO: --------------------------------------------------------------------
  • The linter found an incompatible usage of onClick on line 22 column 22 and four other potential issues in its ViewModel F00633.java file. You can fix these issues before upgrading to Client MVVM or skip upgrading the incompatible ViewModel.
  • For more information on how you can upgrade to Client MVVM, please reference this small talk.

Advanced Customization

Additional properties in the app.properties file:

  • tabSize: By default, the linter assumes a tab size of 4 spaces. If your project uses a different tab size, you can set the tab size to ensure that the reported column numbers match the actual visual positions.
  • jarFiles: If your project relies on external Jar files, providing their absolute paths enables the linter to perform a thorough analysis.
  • disableRules: In cases where certain rules are not applicable to your project, you can selectively disable a subset of the lint rules.

Logging properties in the logger.properties file:

  • handler: By default, the linter uses ConsoleHandler to display output in the terminal. If you prefer to store output in a file, you can switch to FileHandler.
  • java.util.logging.XXX.level: By default, the logging level is set to INFO, which only displays incompatible MVVM files. If you want to see all MVVM files checked by the linter, you can switch to FINE.

To create custom lint rules, follow these steps:

  • Create a new Java class that extends the Rule class and override the getDescription method to provide a short description.
  • Override the newZulFileVisitor and/or newJavaFileVisitor method to return a new instance of your custom ZulFileVisitor or JavaFileVisitor.
  • Inside your custom file visitor, override the visit method for the specific node type you want to inspect and use the report method to publish warnings.
  • Add the package name or the fully-qualified class name to the customRules property in the app.properties file for the rule to be integrated into the linter.

Here’s a sample custom rule class:

package my.pkg;

public class MyRule extends Rule {
    @Override
    protected String getDescription() {
        return "My Custom Rule";
    }

    @Override
    public ZulFileVisitor newZulFileVisitor() {
        return new ZulFileVisitor() {
            @Override
            protected void visitElement(Element node) {
                if (/* insert your conditional logic here */) {
                    report(node, getDescription());
                }
            }
        };
    }

    @Override
    public JavaFileVisitor newJavaFileVisitor() {
        return new JavaFileVisitor() {
            @Override
            protected void visitVariable(VariableTree node) {
                if (/* insert your conditional logic here */) {
                    report(node, getDescription());
                }
            }
        };
    }
}

Through identifying potential compatibility issues, ZK Client MVVM Linter enables developers to make upgrade decisions best suited for their projects, whether that means directly upgrading existing code to ZK 10 Server MVVM or making modifications required for upgrading to Client MVVM.

If you enjoyed this post, please consider leaving a comment or subscribing to the RSS feed to have future articles delivered to your feed reader.

Leave a Reply