Groovy Bitwise Operations Monday, June 3, 2013

long bits = 1L

for (pos in 0..63){
    print pos + ": \t"
    // To set a bit
    bits |= (1L << pos)

    // To unset a bit
    // In this case, unset the one behind the one we just set
    bits &= ~(1L << pos - 1)
    println Long.toBinaryString(bits)
}

Output:

0: 1
1: 10
2: 100
3: 1000
4: 10000
5: 100000
6: 1000000
7: 10000000
8: 100000000
9: 1000000000
10: 10000000000
11: 100000000000
12: 1000000000000
13: 10000000000000
14: 100000000000000
15: 1000000000000000
16: 10000000000000000
17: 100000000000000000
18: 1000000000000000000
19: 10000000000000000000
20: 100000000000000000000
21: 1000000000000000000000
22: 10000000000000000000000
23: 100000000000000000000000
24: 1000000000000000000000000
25: 10000000000000000000000000
26: 100000000000000000000000000
27: 1000000000000000000000000000
28: 10000000000000000000000000000
29: 100000000000000000000000000000
30: 1000000000000000000000000000000
31: 10000000000000000000000000000000
32: 100000000000000000000000000000000
33: 1000000000000000000000000000000000
34: 10000000000000000000000000000000000
35: 100000000000000000000000000000000000
36: 1000000000000000000000000000000000000
37: 10000000000000000000000000000000000000
38: 100000000000000000000000000000000000000
39: 1000000000000000000000000000000000000000
40: 10000000000000000000000000000000000000000
41: 100000000000000000000000000000000000000000
42: 1000000000000000000000000000000000000000000
43: 10000000000000000000000000000000000000000000
44: 100000000000000000000000000000000000000000000
45: 1000000000000000000000000000000000000000000000
46: 10000000000000000000000000000000000000000000000
47: 100000000000000000000000000000000000000000000000
48: 1000000000000000000000000000000000000000000000000
49: 10000000000000000000000000000000000000000000000000
50: 100000000000000000000000000000000000000000000000000
51: 1000000000000000000000000000000000000000000000000000
52: 10000000000000000000000000000000000000000000000000000
53: 100000000000000000000000000000000000000000000000000000
54: 1000000000000000000000000000000000000000000000000000000
55: 10000000000000000000000000000000000000000000000000000000
56: 100000000000000000000000000000000000000000000000000000000
57: 1000000000000000000000000000000000000000000000000000000000
58: 10000000000000000000000000000000000000000000000000000000000
59: 100000000000000000000000000000000000000000000000000000000000
60: 1000000000000000000000000000000000000000000000000000000000000
61: 10000000000000000000000000000000000000000000000000000000000000
62: 100000000000000000000000000000000000000000000000000000000000000
63: 1000000000000000000000000000000000000000000000000000000000000000

Full ZKGrails App: Calling Data Breakout tabs Wednesday, May 29, 2013

This .zul page is dramatically simpler, despite the complexity of the page. The simplicity reflects my improved understanding of how to programmaticly build the ZKGrails component within the Grails composer for this .zul page.



Note: disregard the extra closing tags displayed in the ZUML. Blogger automatically, adds those.

The front-end ZUML code for the complex breakouts tab has been reduced to a single tabbox and tabpanel tag.

See the Grails composer "IntlBillAuditToolComposer.groovy" below.

Note: this .zul page is called from the main .zul page, rendered inside it via an "include" component like this:

    
  
Including the page significantly simplified the design, allowing the content to be easily divided across .zul pages and grails composers. This avoided having one huge grails composer.


    
        

            

                   
               

            
             
              
    


Composer Details


Here is the start of our main "afterCompose()" method, and our call for the data we will need for our data models.

Note: it is feasible to optimize the code to avoid a second call to the DB to retrieve the same data.
def afterCompose = { window ->
        
        /**
         * Prepare date range for 1 year of data
         */
        Calendar cal = Calendar.getInstance()
        cal.add(Calendar.HOUR, +8)
        Calendar cal2 = Calendar.getInstance()
        cal2.add(Calendar.YEAR, -1)
        Date today = cal.getTime()
        Date lastYear = cal2.getTime()

        /**
         * Build Query and get results
         */
        def query = VendorStats.where{
            period in (lastYear .. today)
            vendor.intl == true // Just Domestic
        }
        def results = query.list()
Here we prepare for our later percentage calculations by calling a subroutine which totals our data.
/**
         * Get the totals calculated for all the calls and minutes
         * for
         * L = Lcr (Data from the LCR)
         * A = Actual (Data from the Vendor's bill)
         */
        def totals = getTotals( results )
        def total_L = totals[0]
        def total_A = totals[1]
Here are the details of the "getTotals()" subroutine.
/**
     * Total all the calls and minutes for later percent calculations
     * It takes a collection of "VendorStats"
     * L = LCR value
     * A = Actual bill value
     */
    def getTotals( data ){
        def L = [:]
        def A = [:]
        
        data.each { vs ->
            def month = new SimpleDateFormat("yyyy-MM").format(vs.period)
            def mon = new SimpleDateFormat("MMM").format(vs.period)
            def L_label = "LCR"
            def A_label = "Actual"

            if ( ! L[month] ){ L[month] =   [ "label":L_label, "month":mon, "minutes":0, "cost":0 ] }
            if ( ! A[month] ){ A[month] =   [ "label":A_label, "month":mon, "minutes":0, "cost":0 ] }
         
            if (vs.lcr){ //LCR
                def m = vs.minutes
                def c = vs.cost
                L[month]["minutes"] = L[month]["minutes"] + m
                L[month]["cost"] = L[month]["cost"] + c
                
            } else { //Actual
                def m = vs.minutes
                def c = vs.cost
                A[month]["minutes"] = A[month]["minutes"] + m
                A[month]["cost"] = A[month]["cost"] + c     
            }            
        }
        return [L, A]
    }  
}
Here we compile our main data model in so we can build our various ZK components.
/**
         * Intialize the 4 classes of "Vendor Data" (VD)
         * 
         * I = Int'l value
         * D = Domestic value
         * L = LCR value
         * A = Actual bill value
         */
        def VD = [:]
        def VD_label = "Vendor Data"
        results.each { vs ->
            def vendorName = vs.vendor.name
            def month = new SimpleDateFormat("yyyy-MM").format(vs.period)
            def mon = new SimpleDateFormat("MMM").format(vs.period)
            def L_label = "LCR"
            def A_label = "Actual"
            def L = [:]
            def A = [:]
            
            try {
                if ( ! VD."${month}" ){
                    VD."${month}" = [:]
                }
                if ( ! VD."${month}"."${vendorName}" ){
                    VD."${month}"."${vendorName}" = [:]
                }

                if ( vs.lcr ){ //LCR
                    def lcr = true
                    def cst = vs.cost
                    def min = vs.minutes
                    def sumCost = total_L[month]["cost"]                       
                    def sumMin = total_L[month]["minutes"]
                    def percentCost = cst / sumCost
                    def percentMinutes = min / sumMin
                    L = ["month":month, "mon":mon, "lcr":lcr, 
                         "label2":L_label, "vendorName":vendorName, 
                         "label":VD_label, "cost":cst, "minutes":min, 
                         "percentCost":percentCost, "percentMinutes":percentMinutes, 
                         "sumCost":sumCost, "sumMin":sumMin ]

                    if ( ! VD."${month}"."${vendorName}"."L" ){
                        VD."${month}"."${vendorName}"."L" = [:]
                    }                

                    VD."${month}"."${vendorName}"."L" = L

                } else { //Actual
                    def lcr = false              
                    def cst = vs.cost
                    def min = vs.minutes
                    def sumCost = total_A[month]["cost"]                       
                    def sumMin = total_A[month]["minutes"]
                    def percentCost = cst / sumCost
                    def percentMinutes = min / sumMin                           
                    A = ["month":month, "mon":mon, "lcr":lcr,
                         "label2":A_label, "vendorName":vendorName, 
                         "label":VD_label, "cost":cst, "minutes":min, 
                         "percentCost":percentCost, "percentMinutes":percentMinutes, 
                         "sumCost":sumCost, "sumMin":sumMin ]

                    if ( ! VD."${month}"."${vendorName}"."A" ){
                        VD."${month}"."${vendorName}"."A" = [:]
                    }                     

                    VD."${month}"."${vendorName}"."A" = A
                }
            } catch( NullPointerException e ){
                println "caught: " + e
            }
        }
Here we dynamically build and append our tabbox component with all the needed tabs.
$('#tabbox01').append {
            tabs {
                total_L.each{ m, v ->
                    tab {
                        label = m
                    }
                }
            }    
        }
Here we dynamically build and append our our tabpanels for each month if the data exists. We also fill each of those tabpanels with the rows of data for the appropriate month.
$('#tabpanels01').append {
    total_L.each { m, v ->
        tabpanel {
            grid {
            vflex = 1
            auxhead {
                auxheader {
                    colspan=1
                }
                auxheader {
                    label="LCR"; colspan=2
                }
                auxheader {
                    label="Percentages of Totals"; colspan=2                            
                }                             
                auxheader {
                    label="Actual"; colspan=2
                }
                auxheader {
                    label="Percentages of Totals"; colspan=2                             
                } 
            }

            def list = ["Vendors","Minutes","Cost","% Minutes",
                        "% Cost","Minutes","Cost","% Minutes","% Cost"]
                        
            columns {
                for (i in list){
                    column {
                        label=i; sort="auto"; align="center"
                    }
                }                           
            }

            String moneyPat = "\$##,###.##"
            String minutesPat = "##,###"
            String percentPat = "##.##%"

            def red = "color:red"
. . .(con't) $('#tabpanels01'.append {} call . . .

We build the rows components.
rows {
    VD[m].each { i, j ->
        def vendorName =  i
        def minutes =  j."L"."minutes"
        def cost =  j."L"."cost"
        def percentCost =  j."L"."percentCost"
        def percentMinutes  =  j."L"."percentMinutes"
        def minutes2 =  j."A"."minutes"
        def cost2 =  j."A"."cost"
        def percentCost2 =  j."A"."percentCost"
        def percentMinutes2 =  j."A"."percentMinutes"
                                        
        /**
         * Format values for display
         */                           
        minutes = textFormatService.numberFormatter( minutes, minutesPat )
        cost = textFormatService.numberFormatter( cost, moneyPat )
        
        def form_percentCost = textFormatService.numberFormatter( percentCost, percentPat )
        
        def form_percentMinutes = 
            textFormatService.numberFormatter( percentMinutes, percentPat )

        minutes2 = textFormatService.numberFormatter( minutes2, minutesPat )
        
        cost2 = textFormatService.numberFormatter( cost2, moneyPat )
        
        def form_percentCost2 = 
            textFormatService.numberFormatter( percentCost2, percentPat )
        
        def form_percentMinutes2 = 
            textFormatService.numberFormatter( percentMinutes2, percentPat )
                                       
        row {
            label( value:vendorName )
            label( value:minutes )
            label( value:cost )

            /**
             * Color values red if it is > 100%
             */
            if( percentCost > 1 ){
                label( value:form_percentCost, style:red )
            } else {
                label( value:form_percentCost )
            }
            if( percentMinutes > 1 ){
                label( value:form_percentMinutes, style:red )
            } else {
                label( value:form_percentMinutes )  
            }                                           

            label( value:minutes2 )
            label( value:cost2 )

            /**
             * Color values red if it is > 100%
             */                                    
            if( percentCost2 > 1 ){
                label( value:form_percentCost2, style:red )
            } else {
                label( value:form_percentCost2 )
            }
            if( percentMinutes > 1 ){
                label( value:form_percentMinutes2, style:red )
            } else {
                label( value:form_percentMinutes2 )  
            }                                    

        } //row

Full ZKGrails App: Main Page Zul & Composer Detail

We start by looking at the .zul ZUML component definitions, then following we will see the detail grails composer code found in "BillAuditToolComposer.groovy".




Note: disregard the extra closing tags displayed in the ZUML. Blogger automatically, adds those.

The main page starts with a standard .zul header and "window" component tab.

    
    
        
        
            
        
To wrap all the various kinds of data and charts into tabs, we first define a "tabbox" component, which creates just the visual "tabs" and the label displayed on each. Once those are defined a "tabpanel" is defined, which is rendered under each tab respectively.


    
        
        
        
        
        
        
        
    
We define our first "tabpanels" container component for each of the following "tabpanel" components.

Note: much of the following detail could have been defined programatically inside the grails composer for this zul page. However, this was the first page I started with and was still learning the ins and outs of the ZKGrails builder code. I use more of the programatic logic in the Int'l and Dom 'breakout' pages, which detail the data by month.


    
        
            
            
            
            
                      
        
            
            
            
            
            
            
            
        
        
        
    

The definition of our next tabpanel. It is just a chart of the previous data, and uses the ZK img tag and composer methods show far below. See the ZKGrails builder jQuery-like call $('#intlChart01').

    
                                                    
        
                                
    

The details of this tabpanel are rendered via an "include" component, which calls an entirely different .zul page; a .zul page that has its own grails composer and methods.

    

This begins the definition of our summarized domestic calling data tabpanel.

    
        
            
            
            
            
                      
        
            
            
            
            
            
            
                            
        
        
        
                                                    

We define our domestic data chart tabpanel.

    
                                                    
                                
                            

Again, rather than coding all the complexity of our monthly breakouts, we are just including an entirely separate .zul page that has its own grails composer backing it.

    

We include an entirely separate .zul page, which wraps our Grails scaffolding created CRUD data entry and editing pages.

    

We now close our tabpanels contain component.

Composer Details


The composer contains two major methods for processing and displaying the Domestic and International calling data pulled from the DB. It also, provides several methods for building and displaying the related charts shown in the 2 chart tabs.

Start by injecting a few components into the composer. "Col_month" correspond to ZK components in the corresponding .zul page.
class BillAuditToolComposer extends GrailsComposer {
    def chartService
    def col_month
    def col_month2
    def addDataLabel01 = false
    def addDataLabel02 = false

Most of the backend of the app is defined in the obligatory afterCompose method.

First, get the data we need and build the mail data structure. The app tries to pull a year of data if it exits and uses it to dynamically build the needed ZK components. Since, each row of data on the main page is a monthly summary of information, and because there's "Least Cost Router" (LCR) reported billing information and VoIP vendor reported information, this step is pretty complex.
def afterCompose = { window ->
        
        /**
         * Prepare date range for 1 year of data
         *
         */
        Calendar cal = Calendar.getInstance()
        cal.add(Calendar.HOUR, +8)
        Calendar cal2 = Calendar.getInstance()
        cal2.add(Calendar.YEAR, -1)              
        Date today = cal.getTime()
        Date lastYear = cal2.getTime()

        /**
         * Build Query and get results
         *
         */
        def query = VendorStats.where{
            period in (lastYear .. today)
        }
        def results = query.list()
The data is divided into 4 main structures.
/**
         * Gather data into the models
         * 
         * I = Int'l value
         * D = Domestic value
         * L = LCR value
         * A = Actual bill value
         */ 
        def IL = [:]
        def IA = [:]   
        def DL = [:]
        def DA = [:]
Since the main tabs summarize the International and Domestic calling data, logic is needed to sum the data for each of the the given months.
results.each{ vs ->                
            def month = new SimpleDateFormat("yyyy-MM").format(vs.period)
            def month1 = new SimpleDateFormat("MMM").format(vs.period)
            def IL_label = "Int'l LCR"
            def IA_label = "Int'l Actual"
            def DL_label = "Domestic LCR"
            def DA_label = "Domestic Actual"
            
            if (! IL[month]){ IL[month] = ["label":IL_label, "month":month1, "minutes":0, "cost":0]}
            if (! IA[month]){ IA[month] = ["label":IA_label, "month":month1, "minutes":0, "cost":0]}
            if (! DL[month]){ DL[month] = ["label":DL_label, "month":month1, "minutes":0, "cost":0]}
            if (! DA[month]){ DA[month] = ["label":DA_label, "month":month1, "minutes":0, "cost":0]}

            if (vs.vendor.intl){ //Intl
                if (vs.lcr){ //LCR
                    def m = vs.minutes
                    def c = vs.cost
                    IL[month]["minutes"] = IL[month]["minutes"] + m
                    IL[month]["cost"] = IL[month]["cost"] + c

                } else { //Actual
                    def m = vs.minutes
                    def c = vs.cost
                    IA[month]["minutes"] = IA[month]["minutes"] + m
                    IA[month]["cost"] = IA[month]["cost"] + c 

                }
            } else { //Domestic
                if (vs.lcr){ //LCR
                    def m = vs.minutes
                    def c = vs.cost
                    DL[month]["minutes"] = DL[month]["minutes"] + m
                    DL[month]["cost"] = DL[month]["cost"] + c 

                } else { //Actual
                    def m = vs.minutes
                    def c = vs.cost
                    DA[month]["minutes"] = DA[month]["minutes"] + m
                    DA[month]["cost"] = DA[month]["cost"] + c                    

                }
            }
        }
        

Display the International Call Data


We now process and display Int'l calling data into ZK rows using ZKGrails "rows" & "row" components:
/**
         * Build the Int'l data tab
         *
         */
        $('#rows01').append{
            IL.each{ m, v ->
                def red = "color:red"
                def I_min_diff = 1
                def I_cost_diff = 1
           
                try {
                    if ( IA[m]["minutes"] ){
                        I_min_diff = IL[m]["minutes"] / ( IA[m]["minutes"] )
                    } 
                    if ( IA[m]["cost"] ){
                        I_cost_diff = IL[m]["cost"] / ( IA[m]["cost"] )
                    }

                    String moneyPat = "\$##,###.##"
                    String minutesPat = "##,###"
                    String percentPat = "##.##%"

                    def IL_minutes = numFormer( IL[m]["minutes"], minutesPat )
                    def IL_cost = numFormer( IL[m]["cost"], moneyPat )
                    def IA_minutes = numFormer( IA[m]["minutes"], minutesPat )
                    def IA_cost = numFormer( IA[m]["cost"], moneyPat )
                    def string_I_min_diff = numFormer( I_min_diff, percentPat )
                    def string_I_cost_diff = numFormer( I_cost_diff, percentPat )
The data has just been formatted and now the first row component is built. Note: there is a conditional to color the firgures red if it exceeds a 100%.
row {
                        label(value:m)
                        label(value:IL_minutes)
                        label(value:IL_cost)
                        label(value:IA_minutes)
                        label(value:IA_cost)
                        
                        if( I_min_diff > 1 ){
                            label(value:string_I_min_diff, style:red)
                        } else {
                            label(value:string_I_min_diff)
                        }
                        if( I_cost_diff > 1 ){
                            label(value:string_I_cost_diff, style:red)
                        } else {
                            label(value:string_I_cost_diff)  
                        }

                    }

                } catch( NullPointerException e ){
                    println "caught: " + e
                }                    
            }
            col_month.sort(false)

        }

Display the Domestic Call Data


Next, we process the "Domestic" data, building the row components to be displayed under the domestic tab in the main page.
/**
         * Build the Domestic data tab
         *
         */
        $('#rows02').append{
            DL.each{ m, v ->
                def red = "color:red"                
                def D_min_diff = 1
                def D_cost_diff = 1
                
                try {
                    if ( DA[m]["minutes"] ){
                        D_min_diff = DL[m]["minutes"] / ( DA[m]["minutes"] )
                    }
                    if ( DA[m]["cost"] ){
                        D_cost_diff = DL[m]["cost"] / ( DA[m]["cost"] )
                    }                

                    def moneyPat = "\$##,###.##"
                    def minutesPat = "##,###"
                    def percentPat = "##.##%"

                    def DL_minutes = numFormer( DL[m]["minutes"], minutesPat )
                    def DL_cost = numFormer( DL[m]["cost"], moneyPat )
                    def DA_minutes = numFormer( DA[m]["minutes"], minutesPat )
                    def DA_cost = numFormer( DA[m]["cost"], moneyPat )
                    def string_D_min_diff = numFormer( D_min_diff, percentPat )
                    def string_D_cost_diff = numFormer( D_cost_diff, percentPat )                

                    row {
                        label(value:m)
                        label(value:DL_minutes)
                        label(value:DL_cost)
                        label(value:DA_minutes)
                        label(value:DA_cost)
                        
                        if( D_min_diff > 1 ){
                            label(value:string_D_min_diff, style:red)
                        } else {
                            label(value:string_D_min_diff)
                        }
                        if( D_cost_diff > 1 ){
                            label(value:string_D_cost_diff, style:red)
                        } else {
                            label(value:string_D_cost_diff)  
                        }
                                          
                    }
                
                } catch( NullPointerException e ){
                    println "caught: " + e
                }     
            }
            col_month2.sort(false)
            
        }               

Chart related processes


Here we define the logic for displaying the data labels using the check box component under the Int'l Chart. This features was added because we found the data labels sometimes overlapped, and removing the labels sometimes made it easier to read the chart.
$('#intlDataLabel01').onCheck{
            def id = "#intlChart01"
            
            if ( it.isChecked() ){
                def params = [title:"Int'l: LCR vs Actual Cost", dataLabel:true]
                getChart( IL, IA, id, params )
            } else {
                def params = [title:"Int'l: LCR vs Actual Cost", dataLabel:false]
                getChart( IL, IA, id, params )
            }
        }
        
        $('#intlChart01').append{
            def params = [title:"Int'l: LCR vs Actual Cost", dataLabel:false]
            def chart = chartService.getChart( IL, IA, params )
            def bufferImg = chart.createBufferedImage( 700, 400 )            
            def chartId = $('#intlChart01')
            chartId.setContent( bufferImg )
        }
Now, we compose the charts for the domestic data.
$('#domDataLabel01').onCheck{
            def id = "#domChart01"
            
            if ( it.isChecked() ){
                def params = [title:"Domestic: LCR vs Actual Cost", dataLabel:true]
                getChart( DL, DA, id, params )
            } else {
                def params = [title:"Domestic: LCR vs Actual Cost", dataLabel:false]
                getChart( DL, DA, id, params )
            }
        }
        
        $('#domChart01').append{
            def params = [title:"Domestic: LCR vs Actual Cost", dataLabel:false]
            def chart = chartService.getChart( DL, DA, params )
            def bufferImg = chart.createBufferedImage( 700, 400 )            
            def chartId = $('#domChart01')
            chartId.setContent( bufferImg )
        }                
        
    } //afterCompose()
We have finished our main "afterCompose()" method, and define a couple of utility methods used above.
def getChart( L, A, id, params ){
        def chart = chartService.getChart( L, A, params )
        def bufferImg = chart.createBufferedImage( 700, 400 )            
        def chartId = $( id )
        chartId.setContent( bufferImg )
    }
    
def numFormer( value, pattern ){
        DecimalFormat form = new DecimalFormat(pattern)
        String output = form.format(value)
        return output
    }
    
}

Full ZKGrails App

I work for a company providing a Voice over IP service. We needed a tool to track and audit our billing, i.e., compare what we believe out costs for a given period were, verse what our various service providers say those costs were.

The app uses:
  • Grails 2.2.0
  • ZK 2.1.0
  • jfreechart 1.0.14
First, we will see the layout of the application; then delve into the some of the more interesting ZKGrails, Groovy and Grails elements.

The total data is divided into International and Domestic Calling data, and each of these categories is divided into (Internal) LCR (Least Cost Router) billing data and (external) "Actual" data, which is the data coming from our VoIP calling vendor monthly bills.

The LCR data is basically our internal accounting of the calls made in a given month, i.e., the number of minutes and their cost. The actual data is basically what it cost us to route calls to various phone companies (long distance and international calling providers/vendors)

The data from both internal and external sources is entered by hand into a MySQL database.

This application tries to pull 12 months of data if it exists, categorizes, formats and displays the data in the various tabs.

As stated the 2 main divisions are Int'l and Dom calling data. This data is summarized into monthly totals compiled for all the various domestic and international vendors our company may have used in a given month. Then it is charted across time.

In addition, the data is broken down for each month into the various vendors and displayed for each month.

Finally, there is a data entry and editing tab.


 


Find the implementation details here
Full ZKGrails App: Main Page Zul & Composer Detail

The second tab displays a dynamically drawn chart based on the summarized data.




Here is how the monthly call data is broken down by vendor and displayed.




Find the implementation details here
Full ZKGrails App: Calling Data Breakout tabs

Here is how the Grails scaffolding CRUD interface is wrapped inside the ZKGrails tab. We can enter new vendors.




Here we can enter detailed data for a given vendor.




Again: Find the implementation details in two parts here:
Full ZKGrails App: Main Page Zul & Composer Detail

Full ZKGrails App: Calling Data Breakout tabs

Groovy: Building Nested Maps Friday, May 10, 2013

See Below: Groovy: More Nested Maps

def e = [:]

println "---\n" + e
e."m1" = [:]
e."m2" = [:]
e."m3" = [:]
println "---\n" + e
e."m1"."v1" = [:]
e."m1"."v2" = [:]
e."m1"."v3" = [:]
println "---\n" + e
e."m2"."v1" = [:]
e."m2"."v2" = [:]
e."m2"."v3" = [:]
println "---\n" + e
e."m3"."v1" = [:]
e."m3"."v2" = [:]
e."m3"."v3" = [:]
println "---\n" + e
e."m1"."v1"."L" = [:]
e."m1"."v1"."A" = [:]
e."m1"."v2"."L" = [:]
e."m1"."v2"."A" = [:]
e."m1"."v3"."L" = [:]
e."m1"."v3"."A" = [:]
println "---\n" + e
e."m2"."v1"."L" = [:]
e."m2"."v1"."A" = [:]
e."m2"."v2"."L" = [:]
e."m2"."v2"."A" = [:]
e."m2"."v3"."L" = [:]
e."m2"."v3"."A" = [:]
println "---\n" + e
e."m3"."v1"."L" = [:]
e."m3"."v1"."A" = [:]
e."m3"."v2"."L" = [:]
e."m3"."v2"."A" = [:]
e."m3"."v3"."L" = [:]
e."m3"."v3"."A" = [:]
println "---\n" + e
e."m1"."v1"."L" = [a:1, b:2, c:3]
e."m1"."v1"."A" = [a:4, b:5, c:6]
e."m1"."v2"."L" = [a:7, b:8, c:9]
e."m1"."v2"."A" = [a:10, b:11, c:12]
e."m1"."v3"."L" = [a:13, b:14, c:15]
e."m1"."v3"."A" = [a:16, b:17, c:18]
println "---\n" + e

Output:

[m1:[:]]
---
[m1:[:], m2:[:], m3:[:]]
---
[m1:[v1:[:], v2:[:], v3:[:]], m2:[:], m3:[:]]
---
[m1:[v1:[:], v2:[:], v3:[:]], m2:[v1:[:], v2:[:], v3:[:]], m3:[:]]
---
[m1:[v1:[:], v2:[:], v3:[:]], m2:[v1:[:], v2:[:], v3:[:]], m3:[v1:[:], v2:[:], v3:[:]]]
---
[m1:[v1:[L:[:], A:[:]], v2:[L:[:], A:[:]], v3:[L:[:], A:[:]]], m2:[v1:[:], v2:[:], v3:[:]], m3:[v1:[:], v2:[:], v3:[:]]]
---
[m1:[v1:[L:[:], A:[:]], v2:[L:[:], A:[:]], v3:[L:[:], A:[:]]], m2:[v1:[L:[:], A:[:]], v2:[L:[:], A:[:]], v3:[L:[:], A:[:]]], m3:[v1:[:], v2:[:], v3:[:]]]
---
[m1:[v1:[L:[:], A:[:]], v2:[L:[:], A:[:]], v3:[L:[:], A:[:]]], m2:[v1:[L:[:], A:[:]], v2:[L:[:], A:[:]], v3:[L:[:], A:[:]]], m3:[v1:[L:[:], A:[:]], v2:[L:[:], A:[:]], v3:[L:[:], A:[:]]]]
---
[m1:[v1:[L:[a:1, b:2, c:3], A:[a:4, b:5, c:6]], v2:[L:[a:7, b:8, c:9], A:[a:10, b:11, c:12]], v3:[L:[a:13, b:14, c:15], A:[a:16, b:17, c:18]]], m2:[v1:[L:[:], A:[:]], v2:[L:[:], A:[:]], v3:[L:[:], A:[:]]], m3:[v1:[L:[:], A:[:]], v2:[L:[:], A:[:]], v3:[L:[:], A:[:]]]]

Groovy: More Nested Maps

def d = [
            m1:[ 
                    v1:[ 
                            L:[ a:1, b:2, c:3 ], 
                            A:[ a:4, b:5, c:6 ] 
                       ], 
                    v2:[ 
                            L:[ a:7, b:8, c:9 ], 
                            A:[ a:10, b:11, c:12 ] 
                       ], 
                    v3:[ 
                            L:[ a:13, b:14, c:15 ], 
                            A:[ a:16, b:17, c:18 ] 
                       ] 
               ], 
            m2:[ 
                    v1:[ 
                            L:[ a:19, b:20, c:21 ], 
                            A:[ a:22, b:23, c:24 ] 
                       ], 
                    v2:[ 
                            L:[ a:25, b:26, c:27 ], 
                            A:[ a:28, b:29, c:30 ] 
                       ], 
                    v3:[ 
                            L:[ a:31, b:32, c:33 ], 
                            A:[ a:34, b:35, c:36 ] 
                       ] 
               ], 
            m3:[ 
                    v1:[ 
                            L:[ a:37, b:38, c:39 ], 
                            A:[ a:40, b:41, c:42 ] 
                       ], 
                    v2:[ 
                            L:[ a:43, b:44, c:45 ], 
                            A:[ a:46, b:47, c:48 ] 
                       ], 
                    v3:[ 
                            L:[ a:49, b:50, c:51 ], 
                            A:[ a:52, b:53, c:54 ] 
                       ] 
               ]
        ]

println d

println "---"
println d."m1"."v2"."L"."a"
println d."m2"."v3"."A"."c"
println d."m3"."v1"."A"."b"

Output:

[m1:[v1:[L:[a:1, b:2, c:3], A:[a:4, b:5, c:6]], v2:[L:[a:7, b:8, c:9], A:[a:10, b:11, c:12]], v3:[L:[a:13, b:14, c:15], A:[a:16, b:17, c:18]]], m2:[v1:[L:[a:19, b:20, c:21], A:[a:22, b:23, c:24]], v2:[L:[a:25, b:26, c:27], A:[a:28, b:29, c:30]], v3:[L:[a:31, b:32, c:33], A:[a:34, b:35, c:36]]], m3:[v1:[L:[a:37, b:38, c:39], A:[a:40, b:41, c:42]], v2:[L:[a:43, b:44, c:45], A:[a:46, b:47, c:48]], v3:[L:[a:49, b:50, c:51], A:[a:52, b:53, c:54]]]]
---
7
36
41

Groovy: Nested Maps Thursday, May 9, 2013

def map = [:]

map["a"] = ["b":1]

println map["a"]["b"]
println map."a"."b"

// Can't assign using dot notation
//map."a"."b" = 1  // Cannot set property 'b' on null object

map = ["a":["b":["c":1]]]
map."a"."b"."c"

// Nested lists
map = ["a":["b":["c":[1,2,3],"d":[4,5,6] ] ] ]

println map."a"."b"."c"
println map."a"."b"."d"[2] // Calling index of array

// Nested maps
map = ["a":["b":["c":["c1":1,"c2":2],"d":["d1":4,"d2":5] ] ] ]

println map."a"."b"."c"."c2"
println map."a"."b"."d"."d1"

Gorm: Where Query Between Today and Last Year Tuesday, April 23, 2013

Bizarrely, the GORM where query only accepts the depreciated java.util.Date class.

I was hesitant to write "today - 365" to get last year.

Calendar cal = Calendar.getInstance()
cal.add(Calendar.HOUR, +8)

Calendar cal2 = Calendar.getInstance()
cal2.add(Calendar.YEAR, -1)              

Date today = cal.getTime()
Date lastYear = cal2.getTime()

def query = Stats.where{
    name.id == 1
    period in (lastYear .. today)
}

def results = query.list()
results.each{ println it.period }
Sort the results by the time period with:
results.sort{ it.period }
results.each{ println it.period }

Groovy: Introspect Class Methods

From time to time I need this and can never find it on the web.

def d = new Date()
d.class.methods.each{println it}
d.class.methods.name
Output:

public boolean java.util.Date.equals(java.lang.Object)
public java.lang.String java.util.Date.toString()
public int java.util.Date.hashCode()
public java.lang.Object java.util.Date.clone()
...

[equals, toString, hashCode, clone, compareTo, compareTo, parse, after, before, getDate, getHours, getMinutes, getMonth, getSeconds, getTime, getYear, setTime, setMinutes, setHours, setSeconds, UTC, getDay, setDate, setMonth, setYear, toGMTString, getTimezoneOffset, toLocaleString, wait, wait, wait, getClass, notify, notifyAll]

Also, I found this, which has a more Groovy output:
def dumpOut( clz ) {
  clz.metaClass.methods.each { method ->
    println "${method.returnType.name} ${method.name}( ${method.parameterTypes*.name.join( ', ' )} )"
  }
}

dumpOut String.class 

http://stackoverflow.com/questions

Output:

boolean equals( java.lang.Object )
java.lang.Class getClass( )
int hashCode( )
void notify( )
void notifyAll( )
java.lang.String toString( )
void wait( )
void wait( long )
...

Groovy: Sorting List of Date Strings Monday, April 22, 2013

def list = [
"2013-01-01 0:00:00", "2013-02-01 0:00:00", "2013-03-01 0:00:00", "2013-04-01 0:00:00",
"2009-01-01 0:00:00", "2009-02-01 0:00:00", "2009-03-01 0:00:00", "2009-04-01 0:00:00",
"2008-01-01 0:00:00", "2008-02-01 0:00:00", "2008-03-01 0:00:00", "2008-04-01 0:00:00",
]

Collections.shuffle(list, new Random())

list.each{ println it }

println "-- sorted --"

list.sort()

list.each{ println it }

Output:

2008-03-01 0:00:00
2009-04-01 0:00:00
2009-03-01 0:00:00
2008-02-01 0:00:00
2009-02-01 0:00:00
2013-01-01 0:00:00
2008-04-01 0:00:00
2013-03-01 0:00:00
2013-02-01 0:00:00
2009-01-01 0:00:00
2013-04-01 0:00:00
2008-01-01 0:00:00
-- sorted --
2008-01-01 0:00:00
2008-02-01 0:00:00
2008-03-01 0:00:00
2008-04-01 0:00:00
2009-01-01 0:00:00
2009-02-01 0:00:00
2009-03-01 0:00:00
2009-04-01 0:00:00
2013-01-01 0:00:00
2013-02-01 0:00:00
2013-03-01 0:00:00
2013-04-01 0:00:00

Formatting Number to Currency and Percentage Strings Thursday, April 18, 2013

I found we can use: java.text.DecimalFormat, to take a number like a Integer or a BigDecimal and format it to a string, with the desired formatting:

import java.text.DecimalFormat

def num1 = 654572 //java.lang.Integer
def num2 = 0.7507577625 //java.math.BigDecimal
//println "num1: " + num1.getClass()
//println "num2: " + num2.getClass()

println "Format Currency:"
def list = [0, 1, 6, 23, 245, 8765, 92309, 654572, 6.57, 23.23, 5.876, 5.875, 5.874 ]
list.each{ value ->
    def pattern = "\$##,###.##"
    def moneyform = new DecimalFormat(pattern)
    String output = moneyform.format(value)
    println(value + " " + pattern + " " + output)
}

println "Format Percentage:"
def list1 = [ 0.7507577625, 1.0423815336, 1.1714391045, 0.8603150483 ]
list1.each{ value ->
    def pattern1 = "###.##%"
    def percentform = new DecimalFormat(pattern1)
    String output1 = percentform.format(value)
    println(value + " " + pattern1 + " " + output1)
}
Output:

Format Currency:
0 $##,###.## $0
1 $##,###.## $1
6 $##,###.## $6
23 $##,###.## $23
245 $##,###.## $245
8765 $##,###.## $8,765
92309 $##,###.## $92,309
654572 $##,###.## $654,572
6.57 $##,###.## $6.57
23.23 $##,###.## $23.23
5.876 $##,###.## $5.88
5.875 $##,###.## $5.88
5.874 $##,###.## $5.87

Format Percentage:
0.7507577625 ###.##% 75.08%
1.0423815336 ###.##% 104.24%
1.1714391045 ###.##% 117.14%
0.8603150483 ###.##% 86.03%

Java Tutorial: Decimal Formatting

ZKGrails: Radio Button Example Tuesday, April 16, 2013

The original example can be found here:

ZK: Radio Buttons

ZKGrails Composer:

$('#fruit_rg').onCheck{
    $('#fruit').setValue($('#fruit_rg').selectedItem.label)
    println $('#fruit').value
}

ZKGrails Zul Page:


    
        
        
        
    
    You have selected :
    

Using jFreeChart via a Chart Service Tuesday, April 9, 2013

Using ZKGrails I wanted to use its built-in chart tags. However, since the last time I used ZK (3 years ago) they no longer provide charts in their free version.

FYI, ZKGrails no longer supports having zscript code in the .zul pages, so the process of trying to get a dynamically rendered image embedded into a .zul page was that much more difficult. All the code must be the ZKGrails composer class, so rapid prototyping is out.

The difficulty was compounded by an optional ZKGrails Groovy Builder code supported inside the ZKGrails composers. The builder creates a JQuery like syntax for selecting ZK components from the .zul view. Since it provides a "Groovyer" syntax I wanted to use it, but it did add some mental overhead.

So using jFreeChart I created a Grails service, which just statically returns a jFreeChart. The chart is just a static chart I found in one of the jFreechart demos.

package com.lcr.audit

import org.jfree.chart.ChartFactory
import org.jfree.chart.ChartPanel
import org.jfree.chart.JFreeChart
import org.jfree.chart.plot.PlotOrientation
import org.jfree.chart.plot.XYPlot
import org.jfree.chart.renderer.xy.XYLineAndShapeRenderer
import org.jfree.ui.ApplicationFrame
import org.jfree.ui.RefineryUtilities
import org.jfree.data.category.DefaultCategoryDataset


class ChartService {
    static transactional = false

    def getChart() {
        def dataset = createDataset()
        def chart = createChart(dataset)
        return chart
    }
    
    def createDataset(){
        DefaultCategoryDataset dataset = new DefaultCategoryDataset();
        dataset.addValue(212, "Classes", "JDK 1.0");
        dataset.addValue(504, "Classes", "JDK 1.1");
        dataset.addValue(1520, "Classes", "SDK 1.2");
        dataset.addValue(1842, "Classes", "SDK 1.3");
        dataset.addValue(2991, "Classes", "SDK 1.4");
        return dataset
    }
    
    def createChart(dataset){
            JFreeChart chart = ChartFactory.createLineChart(
            "Java Standard Class Library", // chart title
            "Release", // domain axis label
            "Class Count", // range axis label
            dataset, // data
            PlotOrientation.VERTICAL, // orientation
            false, // include legend
            true, // tooltips
            false // urls
        )
        
        return chart
    }
}

This returns a chart that looks like this:









This image is a jFreechart "chart" object, which provides a method that converts it to a buffered image class. After a great deal of trial and error and searching the web, I found a ZK example that I partially got to work, proving I could render a dynamic image, and the code only needed a buffered image as input.

ZK Demo Dynamic Images


Here is a basic .zul page which will work to render the single dynamic chart from the above chart service:


    
        
            
        
    

The important line is:

The "id" of "img" is what we will use to select this image component and set its content to our chart buffered image.

Now, let's look at the ZKGrails Composer:

package com.lcr.audit

import org.zkoss.zk.grails.composer.*

import org.zkoss.zk.ui.select.annotation.Wire
import org.zkoss.zk.ui.select.annotation.Listen

class DomBillAuditToolComposer extends GrailsComposer {
    def chartService
    def img
    
    def afterCompose = { window ->
        // initialize components here
        def chart = chartService.getChart()
        def bufferImg = chart.createBufferedImage(700, 200)
        img.setContent(bufferImg)
    }
}
This composer is not coded using the ZKGrails Builder JQuery syntax. This was the how I first got it to work. Later, I got help from to get the ZKGrails Builder code to work.

Google Groups: ZKGrails User Group

Lines 10 and 16 are important. "def img" is how we select the ZK Image component from the .zul page. Now, the variable img can be used as it is in line 16 to call the "setContent()" method, so we can pass in our buffered image.

Using the ZKGrails builder code we could do something like this:
$('#img').append{
    def chart = chartService.getChart()
    def bufferImg = chart.createBufferedImage(700, 200)
    def img = $('#chart01') // Or: def img = $('#chart01')[0]
    img.setContent(bufferImg)
}

This is how the ZK image component is selected:
$('#img')

Because we are not appending anything to the "img" ZK Image component, maybe we don't need to select the component like this:
$('#img').append{}

Because notice we are "selecting" the component again in this line.
def img = $('#chart01')
This is similar to what we did in the first composer code above, which uses the older style.

Note: if you have no JQuery background, you may find the JQuery style of having a dollar sign and parentheses $(blah), strange, and very non-Groovy. When I first saw it I had no idea what it was. It is optional, as you can always use the first composer syntax.

Grails Transient Domain Properties Wednesday, April 3, 2013

So far, this is the only official document of a transient property.

Grails Docs Transients

But, I found this interesting nugget:

Question about transient properties

"As of 2.0 if there is only a getter or only a setter method, you don't
need to declare the property name of the method in the transients list.
Only typed fields and get/set pairs that form a property but shouldn't
be persisted need to go in the transients list."

I created domain classes based on this nugget, and it does work.

My domain class just has two methods:

def getPercentMinutes(){ "transient PercentMinutes" }
def getPercentCost(){ "transient PercentCost" }
And does not have a "transients" property.
static transients = ['']
It doesn't need it. Finally, no columns for these properties are created in the DB.

Be careful, do not use a closure as your method call. E.g., don't do this:
def getPercentMinutes = { "transient PercentMinutes" }
def getPercentCost = { "transient PercentCost" }

ZKGrails Doesn't Support zscript in .zul pages Friday, March 29, 2013


According to the ZKGrails creator, Chanwit Kaewkasi, only proper MVC architecture is supported, so no more tags are allowed inside the .zul pages. 

So, therefore, no more rapid prototyping inside the .zul pages. Now, all the coding must be done inside the "composer" classes.

Also, there is a Groovy DSL/Builder to facilitate the coding, but I haven't found any documentation for exactly how to use it yet.

I've been attempting to duplicate a "Grid Hierarchy" like the one found in the ZK Demo page here: http://www.zkoss.org/zkdemo/grid/hierarchy

Inside the composer we may have code like this:

def afterCompose = { window -&gt;  
  // initialize components here  
  def vendors = Vendor.findAll()  
  $('rows').append{  
    vendors.each{ v -&gt;  
      if(v.intl){  
        v.vendorStats.each{ vs -&gt;  
          if(vs.local){  
            row {  
              label(value:v.id)  
              label(value:v.name)  
              label(value:v.intl)  
              label(value:vs.minutes)  
            }  
          }  
        }  
      }  
    }  
  }  
}