Felipe Cypriano You are about to read it

Synchronizing IntelliJ IDEA dependencies with Gradle [Updated]

Based on the great post Managing Intellij dependencies with Gradle from Kallin Nagelberg, I've came to a solution about how to manage Intellij IDEA dependencies on projects that uses .idea directory as its structure.

Basically instead of changing your_project.iml file we create a xml file in .idea/libraries with the jars listed on it. For more details, please, read Kallin's post. This is the task:

// IntelliJ IDEA configuration sync
task intellijSync << {
    final def librariesDir = new File(".idea${File.separator}libraries")
    librariesDir.mkdirs()

    final def gradleLibsPath = configurations.compile.asPath
    final def userHomeGradle = project.gradle.gradleUserHomeDir
    final def libsJar = gradleLibsPath.split(File.pathSeparator).collect {
        it.replaceAll userHomeGradle.path, "\\\$USER_HOME_GRADLE\\\$"
    }
    println libsJar

    final def gradleLibXml = new File(librariesDir, 'Gradle_Libraries.xml')
    gradleLibXml.write """
<component name="libraryTable">
  <library name="Gradle Libraries"/>
</component>
"""
    final def xmlRoot = new XmlParser().parse(gradleLibXml)
    final def classesNode = xmlRoot.library[0].appendNode('CLASSES')

    libsJar.each { jar ->
        classesNode.appendNode('root', [url: "jar://$jar!/"])
    }

    def writer = new StringWriter()
    new XmlNodePrinter(new PrintWriter(writer)).print(xmlRoot)
    println writer.toString()
    gradleLibXml.write writer.toString()
}

The complete build.gradle file is on Gist.

# Update 1

Check the file on Gist, I've updated it to sync test libraries as well.

Grails with ZK: How To Create Components in Runtime with The Builder

ZKGrails plugin has an extremely nice feature which make easier than ever to create ZK components in runtime.

First lets see how is the usual way to create components in runtime using Java. This is the zul representation of what we’re trying to achieve:

<div>
  <toolbarbutton label="Clickable Item" href="#" />
  <toolbarbutton image="edit.png" if="${userHasAccess}" />
  <toolbarbutton image="delete.png" if="${userHasAccess}" />
</div>

And the java code to do the same:

Div div = new Div();
Toolbarbutton tbb = new Toolbarbutton("Clickable Item");
tbb.setHref("#");
tbb.setParent(div);
if (userHasAccess) {
    Toolbarbutton tbbEdit = new Toolbarbutton();
    tbbEdit.setImage("edit.png");
    tbbEdit.setParent(div);
    Toolbarbutton tbbDelete = new Toolbarbutton();
    tbbDelete.setImage("delete.png");
    tbbDelete.setParent(div);
}

As you can easily see the java code is pretty verbose. Using ZKBuilder the code will be easier to understand and smaller, take a look:

Div div = new Div();
div.append {
    toolbarbutton(label: "Clickable Item", href: "#")
    if (userHasAccess) {
        toolbarbutton(image: "edit.png")
        toolbarbutton(image: "delete.png")
    }
}

Which one do your prefer? :) If you want more continue reading to see how to use the builder as a template to a list of items.

Using ZKBuilder as a Template

Grails with ZK: Embedding ZUL in GSP

How about zk pages and gsp were so friends that we could use both together? Imagine the possibility to use Sitemesh to decorate your page or use UrlMapping to choose what the URL will be. Or you could move your project to ZK painlessly, you could update the pages one by one and the new code will work side by side.

ZKGrails plugin 0.7.6 has been released with this great new feature, you can use two simple tags to include any zul page in your GSP. To include the necessary css and javascript into head use <z:head/> and to insert the content anywhre you want in the body of your gsp you'll use <z:body/>.

To see it in practice let's change Grails Quick Start. Follow the steps described there and after you complete all the steps, go back here to update the list.gsp to use ZK Grid component. Don't forget to use Grails 1.1.2 and ZKGrails 0.7.6 at least.

Embedding ZK in GSP

Firstly create this file: grails-app/conf/BuildConfig.groovy and configure ZKGrails repository:

grails.plugin.repos.discovery.zkgrails = "http://zkgrails.googlecode.com/svn/plugins"
grails.plugin.repos.resolveOrder = ['zkgrails','default','core']

Now you can install ZKGrails version 0.7.6 by executing grails install-plugin zk 0.7.6. After installing ZK plugin, create the zul page we'll use: web-app/book/list.zul. You can let this file blank for now, before editing it we need to change automatic scaffolding by creating the the gsp pages  executing this command:

grails generate-views Book

The command will create 4 gsp files in grails-app/views/book: create.gsp, edit.gsp, list.gsp and show.gsp. We will change the list.gsp to instead of use simple HTML table we'll use ZK components. Now let's get back to our web-app/book/list.zul, the objective is to create a grid using zk components and to add a new functionality to delete all selected books. Open list.zul file and put the following code in it:

<?variable-resolver class="org.zkoss.zkplus.spring.DelegatingVariableResolver"?>
<?init class="org.zkoss.zkplus.databind.AnnotateDataBinderInit" arg0="./wnd"?>
<zk xmlns:n="http://www.zkoss.org/2005/zk/native">
    <window id="wnd" apply="${bookListComposer}">
        <listbox id="listBoxBooks" model="@{wnd$composer.booksModel}" checkmark="true" multiple="true"
                 fixedLayout="true" width="500px">
            <listhead>
                <listheader label="ID" sort="auto(id)" width="50px"/>
                <listheader label="Author" sort="auto(author)" width="225px"/>
                <listheader label="Title" sort="auto(title)" width="225px"/>
            </listhead>
            <listitem self="@{each=book}" value="@{book}">
                <listcell label="@{book.id}"/>
                <listcell label="@{book.author}"/>
                <listcell label="@{book.title}"/>
            </listitem>
        </listbox>
        <n:span class="buttons">
            <button id="btnDelete" sclass="delete" mold="os" label="Delete Selected"/>
        </n:span>
    </window>
</zk>

Next step is create the composer for this list.zul page, the composer is the thing that controls the page's behavior, just like a controller. Create a BookListComposer.groovy file in grails-app/composers, and this is the content:

import org.zkoss.zkgrails.*
import org.zkoss.zkplus.databind.BindingListModelList

class BookListComposer extends GrailsComposer {

    def wnd
    def listBoxBooks
    def booksModel
    def binder

    def afterCompose = {
        booksModel = new BindingListModelList([], true)
        reloadBooks()
        binder = wnd.getVariable("binder", true)
    }

    public void onClick_btnDelete() {
        if (listBoxBooks.selectedCount > 0) {
            listBoxBooks.selectedItems.each { listItem ->
                def book = listItem.value
                book.delete(flush: true)
            }
            reloadBooks()
        }
    }

    private def reloadBooks() {
        def books = Book.list()
        booksModel.clear()
        booksModel.addAll(books)
        binder?.loadAll()
    }

}

Now we only need to put the zul page in the list.gsp replacing the HTML <table> tag to <z:body />, the final code is this:

<html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
        <meta name="layout" content="main" />
        <z:head />
        <title>Book List</title>
    </head>
    <body>
        <div class="nav">
            <span class="menuButton"><a class="home" href="${resource(dir:'')}">Home</a></span>
            <span class="menuButton"><g:link class="create" action="create">New Book</g:link></span>
        </div>
        <div class="body">
            <h1>Book List</h1>
            <g:if test="${flash.message}">
            <div class="message">${flash.message}</div>
            </g:if>

            <z:body />
        </div>
    </body>
</html>

As you can see - lines 5 and 19 - we only need to put the tags where we want it's content to be in the page. But you might be wondering where is the path to list.zul file? By default the same convention used by Grails' view, so for our example both tags - head and body - automatically resolves to /book/list.zul. And if you need to specify the files you want you can by setting the attribute zul, like:

<z:body zul="/path/to/file.zul" />

Now we can mashup our both favorite frameworks to make our projects look and behave even better.

# Update 1

Fixed a missing namespace on zul file; and the binder call on BookListComposer. Thanks André.

# Update 2

GitHub repository with full source code used to made this post: http://github.com/fmcypriano/embedding-zul-gsp

Tagged as: , , , 22 Comments

Grails with ZK: Where are my Controllers?

ZK's zul pages works very differently compared to Grails' gsp pages but they have one thing in common both have a class to control the page's state, the behavior of each piece, the data that is showed or is being inserted by the user and this class is called Composer and Controller respectively. This is the second article about my work with ZK and Grails, read the first part before reading this one to get an overview: Grails with ZK Understanding Both Together.

"A [grails] controller handles requests and creates or prepares the response. They can generate the response or delegate to a view.", this is the definition taken from grails website. In other words the controller receives a request do what it has to do and sends the response back.

ZK's composers are a little different, they can do things that you'd need javascript to do using gsp and controllers. The main power of a controller is that you've full control of all components in the page without need to write any javascript code. You could add or remove any component dynamically from the page, register events and whatever more you java and groovy skills let's you do.

Pages Shouldn't Have Any Code

In both technologies you can embed code directly in the page, in gsp you can use scriptlets:

<% items.each {
    total = it.quantity * it.price
}%>

An in zul pages you can use zkscript tags:

<zkscript>
    items.each {
        total = it.quantity * it.price
    }
</zkscript>

It's fairly easy to use code inside the pages and I really do believe you shouldn't do this, it makes your code harder to read and a mess to maintain.

The only places where this kind of code is good is in tutorials and that's why you'll see lots of tutorials using it, but in your actual project the composer/controller should do this job always.

Your First Composer

To demonstrate what a composer does lets create a simple editable page. The page will show a text to the user an the user can click on some buttons to change the text. All the actions will happen without refresh and you won't need to write any javascript.

Create a file named editable.zul in <your-project>/web-app/ with this content:

<your-project>/web-app/editable.zul

<?variable-resolver class="org.zkoss.zkplus.spring.DelegatingVariableResolver"?>

<window id="wndEditable" title="Editable Text" apply="${editableComposer}">
    <div id="divText"/>

    <button id="btnEdit" label="Edit"/>
    <button id="btnSave" label="Save" visible="false"/>
    <button id="btnCancel" label="Cancel" visible="false"/>
</window>

Pay attention to the id attribute it's value will be used in the composer to get the java object corresponding to the component. We create an empty div called 'divText' just to make sure where the text will be in: at the top, before the buttons.

Now let's go to the composer - hooray finally eh -. Create a new directory in grails-app folder called composers and inside this new directory create a file called EditableComposer.groovy.

grails-app/composers/EditableComposer.groovy

import org.zkoss.zkgrails.GrailsComposer
import org.zkoss.zul.*
import org.zkforge.fckez.FCKeditor

class EditableComposer extends GrailsComposer {
    def divText
    def btnEdit
    Button btnSave
    def btnCancel

    FCKeditor editor
    String text

    def afterCompose = {
        // This is code execute just after all the components are created, so you can access them safely
        showText()
        viewMode true
    }

    void onClick_btnEdit() {
        if (!editor) {
            editor = new FCKeditor()
        }
        editor.value = text

        divText.children.clear()
        divText.appendChild editor

        viewMode false
    }

    void onClick_btnSave() {
        text = editor.value
        showText()
        viewMode true
    }

    void onClick_btnCancel() {
        showText()
        viewMode true
    }

    private def showText() {
        text = text ?: "This is my first Composer"

        divText.children.clear()
        divText.appendChild new Html(content: text)
    }

    private def viewMode = { isViewing ->
        btnEdit.visible = isViewing
        btnSave.visible = !btnEdit.visible
        btnCancel.visible = btnSave.visible
    }
}

The components in zul are injected in composer's attributes with the same name as the id on zul file. On line 8 we use a specific type to declare the btnSave, this is just to show you that for each component in zul there's a corresponding java class where you can access and/or change all the attributes. You don't need to worry about thread safety here because for each accessed page a new composer is instantiated, this commonly known as prototype scope.

The afterCompose closure - lines 14 through 18 - is execute just after all the components declared in the zul are created and ready to use, here is the right place to put all your initialization code.

One of the features that I really like is how we can declare events to each component. As you can see in lines 20, 32 and 38 we've declared events to listen to the user clicks on the button for each of the 3 buttons. Basically this is how you declared all kinds events for all components:

public void onEventName_componentId(Event event)

Before the underscore character is the event name and after is the component id. You can set events even for components that you didn't declared as composers attributes.

You don't need to worry about javascript to change the state in the client-side ZK will handle it for you, just change the attributes values in your groovy code and you're done. I highly recommend you give ZK a try and start playing with it, if the application you're developing fits this desktop like model ZK is a great framework to boost your productivity.

See Also:

Tagged as: , , 5 Comments